{-# LANGUAGE OverloadedStrings #-}
module Database.HSparql.Connection
( Database.HSparql.Connection.EndPoint,
BindingValue (..),
selectQuery,
constructQuery,
askQuery,
updateQuery,
describeQuery,
selectQueryRaw,
constructQueryRaw,
askQueryRaw,
updateQueryRaw,
describeQueryRaw,
structureContent,
)
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.Default (def)
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 qualified Data.Text.Lazy.Encoding as EL
import Database.HSparql.QueryGenerator
import Network.Connection (TLSSettings (..))
import Network.HTTP
import Network.HTTP.Conduit
import Network.HTTP.Types.Header
import qualified Network.HTTP.Types.URI as URI
import Text.RDF.RDF4H.TurtleParser
import Text.XML.Light
import Text.XML.Light.Lexer (XmlSource)
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
$cshowsPrec :: Int -> BindingValue -> ShowS
showsPrec :: Int -> BindingValue -> ShowS
$cshow :: BindingValue -> String
show :: BindingValue -> String
$cshowList :: [BindingValue] -> ShowS
showList :: [BindingValue] -> ShowS
Show, BindingValue -> BindingValue -> Bool
(BindingValue -> BindingValue -> Bool)
-> (BindingValue -> BindingValue -> Bool) -> Eq BindingValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BindingValue -> BindingValue -> Bool
== :: BindingValue -> BindingValue -> Bool
$c/= :: BindingValue -> BindingValue -> Bool
/= :: BindingValue -> BindingValue -> Bool
Eq)
sparqlResult :: String -> QName
sparqlResult :: String -> QName
sparqlResult String
s = (String -> QName
unqual String
s) {qURI = Just "http://www.w3.org/2005/sparql-results#"}
structureContent :: (XmlSource a) => a -> Maybe [[BindingValue]]
structureContent :: forall a. XmlSource a => a -> Maybe [[BindingValue]]
structureContent a
s =
do
Element
e <- Maybe Element
doc
[[BindingValue]] -> Maybe [[BindingValue]]
forall a. a -> Maybe a
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 = a -> Maybe Element
forall s. XmlSource s => s -> Maybe Element
parseXMLDoc a
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. HasCallStack => [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
x <- 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
x 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 = "lang", qPrefix = Just "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 :: forall a. Rdf a => 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 :: forall a. Rdf a => 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 contentParams :: [(ByteString, Maybe ByteString)]
contentParams = [(ByteString
"query", ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
T.encodeUtf8 (String -> Text
T.pack String
q)))]
h1 :: (HeaderName, ByteString)
h1 = (HeaderName
hAccept, ByteString
"application/sparql-results+xml")
h2 :: (HeaderName, ByteString)
h2 = (HeaderName
hUserAgent, ByteString
"hsparql-client")
h3 :: (HeaderName, ByteString)
h3 = (HeaderName
hContentType, ByteString
"application/x-www-form-urlencoded")
let request' :: Request
request' = String -> Request
parseRequest_ String
ep
let request :: Request
request =
Request
request'
{ method = "POST",
requestHeaders = [h1, h2, h3],
requestBody = RequestBodyBS (URI.renderQuery False contentParams)
}
let settings :: ManagerSettings
settings = TLSSettings -> Maybe SockSettings -> ManagerSettings
mkManagerSettings (Bool -> Bool -> Bool -> Supported -> TLSSettings
TLSSettingsSimple Bool
True Bool
False Bool
False Supported
forall a. Default a => a
def) Maybe SockSettings
forall a. Maybe a
Nothing
Manager
manager <- IO Manager -> IO Manager
forall a. IO a -> IO a
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 a. a -> IO a
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
$ Text -> Maybe [[BindingValue]]
forall a. XmlSource a => a -> Maybe [[BindingValue]]
structureContent (ByteString -> Text
EL.decodeUtf8 (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 = "GET",
requestHeaders = [h1, h2, h3, h4]
}
let settings :: ManagerSettings
settings = TLSSettings -> Maybe SockSettings -> ManagerSettings
mkManagerSettings (Bool -> Bool -> Bool -> Supported -> TLSSettings
TLSSettingsSimple Bool
True Bool
False Bool
False Supported
forall a. Default a => a
def) Maybe SockSettings
forall a. Maybe a
Nothing
Manager
manager <- IO Manager -> IO Manager
forall a. IO a -> IO a
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 a. a -> IO a
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 a. [a] -> 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 = "POST",
requestHeaders = [h1, h2, h3],
requestBody = RequestBodyBS (T.encodeUtf8 (T.pack body))
}
let settings :: ManagerSettings
settings = TLSSettings -> Maybe SockSettings -> ManagerSettings
mkManagerSettings (Bool -> Bool -> Bool -> Supported -> TLSSettings
TLSSettingsSimple Bool
True Bool
False Bool
False Supported
forall a. Default a => a
def) Maybe SockSettings
forall a. Maybe a
Nothing
Manager
manager <- IO Manager -> IO Manager
forall a. IO a -> IO a
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 a. a -> IO a
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 :: forall a. Rdf a => 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 a. a -> IO 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 :: forall a. Rdf a => 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 a. a -> IO 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 :: forall a. Rdf a => 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 = "GET",
requestHeaders = [h1, h2]
}
let settings :: ManagerSettings
settings = TLSSettings -> Maybe SockSettings -> ManagerSettings
mkManagerSettings (Bool -> Bool -> Bool -> Supported -> TLSSettings
TLSSettingsSimple Bool
True Bool
False Bool
False Supported
forall a. Default a => a
def) Maybe SockSettings
forall a. Maybe a
Nothing
Manager
manager <- IO Manager -> IO Manager
forall a. IO a -> IO a
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 a. a -> IO 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)
forall a.
Rdf a =>
TurtleParser -> 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))