{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} module Text.RDF.RDF4H.ParserUtils ( Parser(..) , parseFromURL -- RDF , rdfTypeNode, rdfNilNode, rdfFirstNode, rdfRestNode , rdfSubjectNode, rdfPredicateNode, rdfObjectNode, rdfStatementNode , rdfTag, rdfID, rdfAbout, rdfParseType, rdfResource, rdfNodeID, rdfDatatype , rdfType, rdfLi, rdfListIndex , rdfDescription, rdfXmlLiteral , rdfAboutEach, rdfAboutEachPrefix, rdfBagID -- XML , xmlLang -- XSD , xsdIntUri, xsdDoubleUri, xsdDecimalUri, xsdBooleanUri -- for GHC 8.0 compatibility #if MIN_VERSION_base(4,10,0) #else , fromRight #endif ) where import Data.RDF.Types import Data.RDF.Namespace import Control.Exception.Lifted import Network.HTTP.Conduit import Data.Text.Encoding (decodeUtf8) #if MIN_VERSION_base(4,9,0) #if !MIN_VERSION_base(4,11,0) import Data.Semigroup ((<>)) #else #endif #else #endif import qualified Data.ByteString.Lazy as BS import Data.Text (Text) import qualified Data.Text as T #if MIN_VERSION_base(4,10,0) #else fromRight :: b -> Either a b -> b fromRight _ (Right b) = b fromRight b _ = b #endif data Parser = Parsec | Attoparsec -- | A convenience function for terminating a parse with a parse failure, using -- the given error message as the message for the failure. errResult :: String -> Either ParseFailure (RDF rdfImpl) errResult msg = Left (ParseFailure msg) parseFromURL :: (T.Text -> Either ParseFailure (RDF rdfImpl)) -> String -> IO (Either ParseFailure (RDF rdfImpl)) parseFromURL parseFunc url = do result <- Control.Exception.Lifted.try $ simpleHttp url case result of Left (err :: HttpException) -> case err of (HttpExceptionRequest _req content) -> case content of ConnectionTimeout -> return $ errResult "Connection timed out" _ -> return $ errResult ("HttpExceptionRequest content: " <> show content) (InvalidUrlException{}) -> return $ errResult "Invalid URL exception" Right bs -> do let s = decodeUtf8 $ BS.toStrict bs return (parseFunc s) rdfTypeNode, rdfNilNode, rdfFirstNode, rdfRestNode :: Node rdfTypeNode = UNode $ mkUri rdf "type" rdfNilNode = UNode $ mkUri rdf "nil" rdfFirstNode = UNode $ mkUri rdf "first" rdfRestNode = UNode $ mkUri rdf "rest" rdfSubjectNode, rdfPredicateNode, rdfObjectNode, rdfStatementNode :: Node rdfSubjectNode = UNode $ mkUri rdf "subject" rdfPredicateNode = UNode $ mkUri rdf "predicate" rdfObjectNode = UNode $ mkUri rdf "object" rdfStatementNode = UNode $ mkUri rdf "Statement" -- Core terms rdfTag, rdfID, rdfAbout, rdfParseType, rdfResource, rdfNodeID, rdfDatatype :: Text rdfTag = mkUri rdf "RDF" rdfID = mkUri rdf "ID" rdfAbout = mkUri rdf "about" rdfParseType = mkUri rdf "parseType" rdfResource = mkUri rdf "resource" rdfNodeID = mkUri rdf "nodeID" rdfDatatype = mkUri rdf "datatype" rdfType, rdfLi, rdfListIndex :: Text rdfType = mkUri rdf "type" rdfLi = mkUri rdf "li" rdfListIndex = mkUri rdf "_" rdfXmlLiteral, rdfDescription :: Text rdfXmlLiteral = mkUri rdf "XMLLiteral" rdfDescription = mkUri rdf "Description" -- Old terms rdfAboutEach, rdfAboutEachPrefix, rdfBagID :: Text rdfAboutEach = mkUri rdf "aboutEach" rdfAboutEachPrefix = mkUri rdf "aboutEachPrefix" rdfBagID = mkUri rdf "bagID" xmlLang :: Text xmlLang = mkUri xml "lang" xsdIntUri, xsdDoubleUri, xsdDecimalUri, xsdBooleanUri :: Text xsdIntUri = mkUri xsd "integer" xsdDoubleUri = mkUri xsd "double" xsdDecimalUri = mkUri xsd "decimal" xsdBooleanUri = mkUri xsd "boolean"