{-# LANGUAGE OverloadedStrings #-}
module Database.HSparql.Connection
( Database.HSparql.Connection.EndPoint,
BindingValue (..),
selectQuery,
constructQuery,
askQuery,
updateQuery,
describeQuery,
selectQueryRaw,
constructQueryRaw,
askQueryRaw,
updateQueryRaw,
describeQueryRaw,
)
where
import Control.Monad
import Control.Monad.IO.Class
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Lazy.Char8 as LB
import Data.Maybe (isJust, mapMaybe)
import qualified Data.RDF as RDF
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
import qualified Data.Text.Encoding as T
import Database.HSparql.QueryGenerator
import Network.Connection (TLSSettings (..))
import Network.HTTP
import Network.HTTP.Conduit
import Network.HTTP.Types.Header
import Text.RDF.RDF4H.TurtleParser
import Text.XML.Light
type EndPoint = String
data BindingValue
=
Bound RDF.Node
|
Unbound
deriving (Int -> BindingValue -> ShowS
[BindingValue] -> ShowS
BindingValue -> String
(Int -> BindingValue -> ShowS)
-> (BindingValue -> String)
-> ([BindingValue] -> ShowS)
-> Show BindingValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BindingValue] -> ShowS
$cshowList :: [BindingValue] -> ShowS
show :: BindingValue -> String
$cshow :: BindingValue -> String
showsPrec :: Int -> BindingValue -> ShowS
$cshowsPrec :: Int -> BindingValue -> ShowS
Show, BindingValue -> BindingValue -> Bool
(BindingValue -> BindingValue -> Bool)
-> (BindingValue -> BindingValue -> Bool) -> Eq BindingValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BindingValue -> BindingValue -> Bool
$c/= :: BindingValue -> BindingValue -> Bool
== :: BindingValue -> BindingValue -> Bool
$c== :: BindingValue -> BindingValue -> Bool
Eq)
sparqlResult :: String -> QName
sparqlResult :: String -> QName
sparqlResult String
s = (String -> QName
unqual String
s) {qURI :: Maybe String
qURI = String -> Maybe String
forall a. a -> Maybe a
Just String
"http://www.w3.org/2005/sparql-results#"}
structureContent :: String -> Maybe [[BindingValue]]
structureContent :: String -> Maybe [[BindingValue]]
structureContent String
s =
do
Element
e <- Maybe Element
doc
[[BindingValue]] -> Maybe [[BindingValue]]
forall (m :: * -> *) a. Monad m => a -> m a
return ([[BindingValue]] -> Maybe [[BindingValue]])
-> [[BindingValue]] -> Maybe [[BindingValue]]
forall a b. (a -> b) -> a -> b
$ (Element -> [BindingValue]) -> [Element] -> [[BindingValue]]
forall a b. (a -> b) -> [a] -> [b]
map ([String] -> Element -> [BindingValue]
projectResult ([String] -> Element -> [BindingValue])
-> [String] -> Element -> [BindingValue]
forall a b. (a -> b) -> a -> b
$ Element -> [String]
vars Element
e) ([Element] -> [[BindingValue]]) -> [Element] -> [[BindingValue]]
forall a b. (a -> b) -> a -> b
$ QName -> Element -> [Element]
findElements (String -> QName
sparqlResult String
"result") Element
e
where
doc :: Maybe Element
doc :: Maybe Element
doc = String -> Maybe Element
forall s. XmlSource s => s -> Maybe Element
parseXMLDoc String
s
vars :: Element -> [String]
vars :: Element -> [String]
vars = (Element -> Maybe String) -> [Element] -> [String]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (QName -> Element -> Maybe String
findAttr (QName -> Element -> Maybe String)
-> QName -> Element -> Maybe String
forall a b. (a -> b) -> a -> b
$ String -> QName
unqual String
"name") ([Element] -> [String])
-> (Element -> [Element]) -> Element -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QName -> Element -> [Element]
findElements (String -> QName
sparqlResult String
"variable")
projectResult :: [String] -> Element -> [BindingValue]
projectResult :: [String] -> Element -> [BindingValue]
projectResult [String]
vs Element
e = (String -> BindingValue) -> [String] -> [BindingValue]
forall a b. (a -> b) -> [a] -> [b]
map String -> BindingValue
pVar [String]
vs
where
pVar :: String -> BindingValue
pVar String
v = BindingValue
-> (Element -> BindingValue) -> Maybe Element -> BindingValue
forall b a. b -> (a -> b) -> Maybe a -> b
maybe BindingValue
Unbound (Element -> BindingValue
value (Element -> BindingValue)
-> (Element -> Element) -> Element -> BindingValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Element] -> Element
forall a. [a] -> a
head ([Element] -> Element)
-> (Element -> [Element]) -> Element -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> [Element]
elChildren) (Maybe Element -> BindingValue) -> Maybe Element -> BindingValue
forall a b. (a -> b) -> a -> b
$ (Element -> Bool) -> Element -> Maybe Element
filterElement (String -> Element -> Bool
pred_ String
v) Element
e
pred_ :: String -> Element -> Bool
pred_ String
v Element
e' = Maybe () -> Bool
forall a. Maybe a -> Bool
isJust (Maybe () -> Bool) -> Maybe () -> Bool
forall a b. (a -> b) -> a -> b
$ do
String
a <- QName -> Element -> Maybe String
findAttr (String -> QName
unqual String
"name") Element
e'
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ String
a String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
v
value :: Element -> BindingValue
value :: Element -> BindingValue
value Element
e =
case QName -> String
qName (Element -> QName
elName Element
e) of
String
"uri" -> Node -> BindingValue
Bound (Node -> BindingValue) -> Node -> BindingValue
forall a b. (a -> b) -> a -> b
$ Text -> Node
RDF.unode (Text -> Node) -> Text -> Node
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Element -> String
strContent Element
e
String
"literal" -> case QName -> Element -> Maybe String
findAttr (String -> QName
unqual String
"datatype") Element
e of
Just String
dt -> Node -> BindingValue
Bound (Node -> BindingValue) -> Node -> BindingValue
forall a b. (a -> b) -> a -> b
$ LValue -> Node
RDF.lnode (LValue -> Node) -> LValue -> Node
forall a b. (a -> b) -> a -> b
$ Text -> Text -> LValue
RDF.typedL (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Element -> String
strContent Element
e) (String -> Text
T.pack String
dt)
Maybe String
Nothing -> case QName -> Element -> Maybe String
findAttr QName
langAttr Element
e of
Just String
lang_ -> Node -> BindingValue
Bound (Node -> BindingValue) -> Node -> BindingValue
forall a b. (a -> b) -> a -> b
$ LValue -> Node
RDF.lnode (LValue -> Node) -> LValue -> Node
forall a b. (a -> b) -> a -> b
$ Text -> Text -> LValue
RDF.plainLL (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Element -> String
strContent Element
e) (String -> Text
T.pack String
lang_)
Maybe String
Nothing -> Node -> BindingValue
Bound (Node -> BindingValue) -> Node -> BindingValue
forall a b. (a -> b) -> a -> b
$ LValue -> Node
RDF.lnode (LValue -> Node) -> LValue -> Node
forall a b. (a -> b) -> a -> b
$ Text -> LValue
RDF.plainL (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Element -> String
strContent Element
e)
String
_ -> BindingValue
Unbound
langAttr :: QName
langAttr :: QName
langAttr = QName
blank_name {qName :: String
qName = String
"lang", qPrefix :: Maybe String
qPrefix = String -> Maybe String
forall a. a -> Maybe a
Just String
"xml"}
parseAsk :: String -> Bool
parseAsk :: String -> Bool
parseAsk String
s
| String
s' String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"true" Bool -> Bool -> Bool
|| String
s' String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"yes" = Bool
True
| String
s' String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"false" Bool -> Bool -> Bool
|| String
s' String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"no" = Bool
False
| Bool
otherwise = String -> Bool
forall a. HasCallStack => String -> a
error (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ String
"Unexpected Ask response: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s
where
s' :: String
s' = ShowS
forall a. [a] -> [a]
reverse ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n') ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
forall a. [a] -> [a]
reverse String
s
parseUpdate :: String -> Bool
parseUpdate :: String -> Bool
parseUpdate String
s
| String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"" = Bool
True
| Bool
otherwise = String -> Bool
forall a. HasCallStack => String -> a
error (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ String
"Unexpected Update response: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s
selectQuery :: Database.HSparql.Connection.EndPoint -> Query SelectQuery -> IO (Maybe [[BindingValue]])
selectQuery :: String -> Query SelectQuery -> IO (Maybe [[BindingValue]])
selectQuery String
ep Query SelectQuery
q = String -> String -> IO (Maybe [[BindingValue]])
selectQueryRaw String
ep (Query SelectQuery -> String
createSelectQuery Query SelectQuery
q)
askQuery :: Database.HSparql.Connection.EndPoint -> Query AskQuery -> IO Bool
askQuery :: String -> Query AskQuery -> IO Bool
askQuery String
ep Query AskQuery
q = String -> String -> IO Bool
askQueryRaw String
ep (Query AskQuery -> String
createAskQuery Query AskQuery
q)
updateQuery :: Database.HSparql.Connection.EndPoint -> Query UpdateQuery -> IO Bool
updateQuery :: String -> Query UpdateQuery -> IO Bool
updateQuery String
ep Query UpdateQuery
q = String -> String -> IO Bool
updateQueryRaw String
ep (Query UpdateQuery -> String
createUpdateQuery Query UpdateQuery
q)
constructQuery :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> Query ConstructQuery -> IO (RDF.RDF a)
constructQuery :: String -> Query ConstructQuery -> IO (RDF a)
constructQuery String
ep Query ConstructQuery
q = String -> String -> IO (RDF a)
forall a. Rdf a => String -> String -> IO (RDF a)
constructQueryRaw String
ep (Query ConstructQuery -> String
createConstructQuery Query ConstructQuery
q)
describeQuery :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> Query DescribeQuery -> IO (RDF.RDF a)
describeQuery :: String -> Query DescribeQuery -> IO (RDF a)
describeQuery String
ep Query DescribeQuery
q = String -> String -> IO (RDF a)
forall a. Rdf a => String -> String -> IO (RDF a)
describeQueryRaw String
ep (Query DescribeQuery -> String
createDescribeQuery Query DescribeQuery
q)
selectQueryRaw :: Database.HSparql.Connection.EndPoint -> String -> IO (Maybe [[BindingValue]])
selectQueryRaw :: String -> String -> IO (Maybe [[BindingValue]])
selectQueryRaw String
ep String
q = do
let uri :: String
uri = String
ep String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"?" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [(String, String)] -> String
urlEncodeVars [(String
"query", String
q)]
h1 :: (HeaderName, ByteString)
h1 = (HeaderName
hAccept, ByteString
"application/sparql-results+xml")
h2 :: (HeaderName, ByteString)
h2 = (HeaderName
hUserAgent, ByteString
"hsparql-client")
Request
request' <- String -> IO Request
forall (m :: * -> *). MonadThrow m => String -> m Request
parseRequest String
uri
let request :: Request
request =
Request
request'
{ method :: ByteString
method = ByteString
"GET",
requestHeaders :: RequestHeaders
requestHeaders = [(HeaderName, ByteString)
h1, (HeaderName, ByteString)
h2]
}
let settings :: ManagerSettings
settings = TLSSettings -> Maybe SockSettings -> ManagerSettings
mkManagerSettings (Bool -> Bool -> Bool -> TLSSettings
TLSSettingsSimple Bool
True Bool
False Bool
False) Maybe SockSettings
forall a. Maybe a
Nothing
Manager
manager <- IO Manager -> IO Manager
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Manager -> IO Manager) -> IO Manager -> IO Manager
forall a b. (a -> b) -> a -> b
$ ManagerSettings -> IO Manager
newManager ManagerSettings
settings
Response ByteString
resp <- Request -> Manager -> IO (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Request -> Manager -> m (Response ByteString)
httpLbs Request
request Manager
manager
Maybe [[BindingValue]] -> IO (Maybe [[BindingValue]])
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe [[BindingValue]] -> IO (Maybe [[BindingValue]]))
-> Maybe [[BindingValue]] -> IO (Maybe [[BindingValue]])
forall a b. (a -> b) -> a -> b
$ String -> Maybe [[BindingValue]]
structureContent (ByteString -> String
LB.unpack (Response ByteString -> ByteString
forall body. Response body -> body
responseBody Response ByteString
resp))
askQueryRaw :: Database.HSparql.Connection.EndPoint -> String -> IO Bool
askQueryRaw :: String -> String -> IO Bool
askQueryRaw String
ep String
q = do
let uri :: String
uri = String
ep String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"?" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [(String, String)] -> String
urlEncodeVars [(String
"query", String
q)]
h1 :: (HeaderName, ByteString)
h1 = (HeaderName
hUserAgent, ByteString
"hsparql-client")
h2 :: (HeaderName, ByteString)
h2 = (HeaderName
hAccept, ByteString
"text/plain")
h3 :: (HeaderName, ByteString)
h3 = (HeaderName
hAccept, ByteString
"text/boolean")
h4 :: (HeaderName, ByteString)
h4 = (HeaderName
hAcceptCharset, ByteString
"utf-8")
Request
request' <- String -> IO Request
forall (m :: * -> *). MonadThrow m => String -> m Request
parseRequest String
uri
let request :: Request
request =
Request
request'
{ method :: ByteString
method = ByteString
"GET",
requestHeaders :: RequestHeaders
requestHeaders = [(HeaderName, ByteString)
h1, (HeaderName, ByteString)
h2, (HeaderName, ByteString)
h3, (HeaderName, ByteString)
h4]
}
let settings :: ManagerSettings
settings = TLSSettings -> Maybe SockSettings -> ManagerSettings
mkManagerSettings (Bool -> Bool -> Bool -> TLSSettings
TLSSettingsSimple Bool
True Bool
False Bool
False) Maybe SockSettings
forall a. Maybe a
Nothing
Manager
manager <- IO Manager -> IO Manager
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Manager -> IO Manager) -> IO Manager -> IO Manager
forall a b. (a -> b) -> a -> b
$ ManagerSettings -> IO Manager
newManager ManagerSettings
settings
Response ByteString
resp <- Request -> Manager -> IO (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Request -> Manager -> m (Response ByteString)
httpLbs Request
request Manager
manager
Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ String -> Bool
parseAsk (ByteString -> String
LB.unpack (Response ByteString -> ByteString
forall body. Response body -> body
responseBody Response ByteString
resp))
updateQueryRaw :: Database.HSparql.Connection.EndPoint -> String -> IO Bool
updateQueryRaw :: String -> String -> IO Bool
updateQueryRaw String
ep String
q = do
let uri :: String
uri = String
ep
body :: String
body = String
q
h1 :: (HeaderName, ByteString)
h1 = (HeaderName
hContentLength, String -> ByteString
B.pack (Int -> String
forall a. Show a => a -> String
show (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
body)))
h2 :: (HeaderName, ByteString)
h2 = (HeaderName
hContentType, ByteString
"application/sparql-update")
h3 :: (HeaderName, ByteString)
h3 = (HeaderName
hUserAgent, ByteString
"hsparql-client")
Request
request' <- String -> IO Request
forall (m :: * -> *). MonadThrow m => String -> m Request
parseRequest String
uri
let request :: Request
request =
Request
request'
{ method :: ByteString
method = ByteString
"POST",
requestHeaders :: RequestHeaders
requestHeaders = [(HeaderName, ByteString)
h1, (HeaderName, ByteString)
h2, (HeaderName, ByteString)
h3],
requestBody :: RequestBody
requestBody = ByteString -> RequestBody
RequestBodyBS (Text -> ByteString
T.encodeUtf8 (String -> Text
T.pack String
body))
}
let settings :: ManagerSettings
settings = TLSSettings -> Maybe SockSettings -> ManagerSettings
mkManagerSettings (Bool -> Bool -> Bool -> TLSSettings
TLSSettingsSimple Bool
True Bool
False Bool
False) Maybe SockSettings
forall a. Maybe a
Nothing
Manager
manager <- IO Manager -> IO Manager
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Manager -> IO Manager) -> IO Manager -> IO Manager
forall a b. (a -> b) -> a -> b
$ ManagerSettings -> IO Manager
newManager ManagerSettings
settings
Response ByteString
resp <- Request -> Manager -> IO (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Request -> Manager -> m (Response ByteString)
httpLbs Request
request Manager
manager
Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ String -> Bool
parseUpdate (ByteString -> String
LB.unpack (Response ByteString -> ByteString
forall body. Response body -> body
responseBody Response ByteString
resp))
constructQueryRaw :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> String -> IO (RDF.RDF a)
constructQueryRaw :: String -> String -> IO (RDF a)
constructQueryRaw String
ep String
q = do
let uri :: String
uri = String
ep String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"?" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [(String, String)] -> String
urlEncodeVars [(String
"query", String
q)]
Either ParseFailure (RDF a)
rdfGraph <- String -> IO (Either ParseFailure (RDF a))
forall a. Rdf a => String -> IO (Either ParseFailure (RDF a))
httpCallForRdf String
uri
case Either ParseFailure (RDF a)
rdfGraph of
Left ParseFailure
e -> String -> IO (RDF a)
forall a. HasCallStack => String -> a
error (String -> IO (RDF a)) -> String -> IO (RDF a)
forall a b. (a -> b) -> a -> b
$ ParseFailure -> String
forall a. Show a => a -> String
show ParseFailure
e
Right RDF a
graph -> RDF a -> IO (RDF a)
forall (m :: * -> *) a. Monad m => a -> m a
return RDF a
graph
describeQueryRaw :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> String -> IO (RDF.RDF a)
describeQueryRaw :: String -> String -> IO (RDF a)
describeQueryRaw String
ep String
q = do
let uri :: String
uri = String
ep String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"?" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [(String, String)] -> String
urlEncodeVars [(String
"query", String
q)]
Either ParseFailure (RDF a)
rdfGraph <- String -> IO (Either ParseFailure (RDF a))
forall a. Rdf a => String -> IO (Either ParseFailure (RDF a))
httpCallForRdf String
uri
case Either ParseFailure (RDF a)
rdfGraph of
Left ParseFailure
e -> String -> IO (RDF a)
forall a. HasCallStack => String -> a
error (String -> IO (RDF a)) -> String -> IO (RDF a)
forall a b. (a -> b) -> a -> b
$ ParseFailure -> String
forall a. Show a => a -> String
show ParseFailure
e
Right RDF a
graph -> RDF a -> IO (RDF a)
forall (m :: * -> *) a. Monad m => a -> m a
return RDF a
graph
httpCallForRdf :: RDF.Rdf a => String -> IO (Either RDF.ParseFailure (RDF.RDF a))
httpCallForRdf :: String -> IO (Either ParseFailure (RDF a))
httpCallForRdf String
uri = do
let h1 :: (HeaderName, ByteString)
h1 = (HeaderName
hUserAgent, ByteString
"hsparql-client")
h2 :: (HeaderName, ByteString)
h2 = (HeaderName
hAccept, ByteString
"text/turtle")
Request
request' <- String -> IO Request
forall (m :: * -> *). MonadThrow m => String -> m Request
parseRequest String
uri
let request :: Request
request =
Request
request'
{ method :: ByteString
method = ByteString
"GET",
requestHeaders :: RequestHeaders
requestHeaders = [(HeaderName, ByteString)
h1, (HeaderName, ByteString)
h2]
}
let settings :: ManagerSettings
settings = TLSSettings -> Maybe SockSettings -> ManagerSettings
mkManagerSettings (Bool -> Bool -> Bool -> TLSSettings
TLSSettingsSimple Bool
True Bool
False Bool
False) Maybe SockSettings
forall a. Maybe a
Nothing
Manager
manager <- IO Manager -> IO Manager
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Manager -> IO Manager) -> IO Manager -> IO Manager
forall a b. (a -> b) -> a -> b
$ ManagerSettings -> IO Manager
newManager ManagerSettings
settings
Response ByteString
resp <- Request -> Manager -> IO (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Request -> Manager -> m (Response ByteString)
httpLbs Request
request Manager
manager
Either ParseFailure (RDF a) -> IO (Either ParseFailure (RDF a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ParseFailure (RDF a) -> IO (Either ParseFailure (RDF a)))
-> Either ParseFailure (RDF a) -> IO (Either ParseFailure (RDF a))
forall a b. (a -> b) -> a -> b
$ TurtleParser -> Text -> Either ParseFailure (RDF a)
forall p a.
(RdfParser p, Rdf a) =>
p -> Text -> Either ParseFailure (RDF a)
RDF.parseString (Maybe BaseUrl -> Maybe Text -> TurtleParser
TurtleParser Maybe BaseUrl
forall a. Maybe a
Nothing Maybe Text
forall a. Maybe a
Nothing) (Text -> Either ParseFailure (RDF a))
-> Text -> Either ParseFailure (RDF a)
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
E.decodeUtf8 (ByteString -> ByteString
LB.toStrict (Response ByteString -> ByteString
forall body. Response body -> body
responseBody Response ByteString
resp))