{-# LANGUAGE OverloadedStrings #-}
module Data.RDF.Parser.NQuads (
Result
, parseNQuads
, parseTriple
, parseQuad
, parseQuadLine
, foldGraphs
, foldResults
) where
import qualified Data.Attoparsec.Text as A
import qualified Data.Attoparsec.Text.Lazy as AL
import Data.RDF.Types
import Data.RDF.Parser.Common
import qualified Data.Text.Lazy as TL
type Result = Either String RDFGraph
parseNQuads :: TL.Text -> [Result]
parseNQuads :: Text -> [Result]
parseNQuads = [Either String Quad] -> [Result]
foldResults
([Either String Quad] -> [Result])
-> (Text -> [Either String Quad]) -> Text -> [Result]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Either String Quad) -> [Text] -> [Either String Quad]
forall a b. (a -> b) -> [a] -> [b]
map (Result Quad -> Either String Quad
forall r. Result r -> Either String r
AL.eitherResult (Result Quad -> Either String Quad)
-> (Text -> Result Quad) -> Text -> Either String Quad
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser Quad -> Text -> Result Quad
forall a. Parser a -> Text -> Result a
AL.parse Parser Quad
parseQuad)
([Text] -> [Either String Quad])
-> (Text -> [Text]) -> Text -> [Either String Quad]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
TL.lines
foldGraphs :: [Quad] -> [RDFGraph]
foldGraphs :: [Quad] -> [RDFGraph]
foldGraphs [] = []
foldGraphs (Quad
quad:[Quad]
quads) = RDFGraph -> [Quad] -> [RDFGraph]
go (Maybe IRI -> [Triple] -> RDFGraph
RDFGraph (Quad -> Maybe IRI
quadGraph Quad
quad) [Quad -> Triple
quadTriple Quad
quad]) [Quad]
quads
where go :: RDFGraph -> [Quad] -> [RDFGraph]
go RDFGraph
g [] = [RDFGraph
g]
go g :: RDFGraph
g@(RDFGraph Maybe IRI
gl [Triple]
ts) (Quad
q:[Quad]
qs)
| Maybe IRI
gl Maybe IRI -> Maybe IRI -> Bool
forall a. Eq a => a -> a -> Bool
== Quad -> Maybe IRI
quadGraph Quad
q = RDFGraph -> [Quad] -> [RDFGraph]
go (Maybe IRI -> [Triple] -> RDFGraph
RDFGraph Maybe IRI
gl (Quad -> Triple
quadTriple Quad
qTriple -> [Triple] -> [Triple]
forall a. a -> [a] -> [a]
:[Triple]
ts)) [Quad]
qs
| Bool
otherwise = RDFGraph
g RDFGraph -> [RDFGraph] -> [RDFGraph]
forall a. a -> [a] -> [a]
: RDFGraph -> [Quad] -> [RDFGraph]
go (Maybe IRI -> [Triple] -> RDFGraph
RDFGraph (Quad -> Maybe IRI
quadGraph Quad
q)
[Quad -> Triple
quadTriple Quad
q]) [Quad]
qs
foldResults :: [Either String Quad] -> [Result]
foldResults :: [Either String Quad] -> [Result]
foldResults [] = []
foldResults (Left String
e:[Either String Quad]
quads) = String -> Result
forall a b. a -> Either a b
Left String
e Result -> [Result] -> [Result]
forall a. a -> [a] -> [a]
: [Either String Quad] -> [Result]
foldResults [Either String Quad]
quads
foldResults (Right Quad
quad:[Either String Quad]
quads) = RDFGraph -> [Either String Quad] -> [Result]
go (Maybe IRI -> [Triple] -> RDFGraph
RDFGraph (Quad -> Maybe IRI
quadGraph Quad
quad)
[Quad -> Triple
quadTriple Quad
quad])
[Either String Quad]
quads
where go :: RDFGraph -> [Either String Quad] -> [Result]
go RDFGraph
g [] = [RDFGraph -> Result
forall a b. b -> Either a b
Right RDFGraph
g]
go RDFGraph
g (Left String
e:[Either String Quad]
qs) = RDFGraph -> Result
forall a b. b -> Either a b
Right RDFGraph
g Result -> [Result] -> [Result]
forall a. a -> [a] -> [a]
: String -> Result
forall a b. a -> Either a b
Left String
e Result -> [Result] -> [Result]
forall a. a -> [a] -> [a]
: [Either String Quad] -> [Result]
foldResults [Either String Quad]
qs
go g :: RDFGraph
g@(RDFGraph Maybe IRI
gl [Triple]
ts) (Right Quad
q:[Either String Quad]
qs)
| Maybe IRI
gl Maybe IRI -> Maybe IRI -> Bool
forall a. Eq a => a -> a -> Bool
== Quad -> Maybe IRI
quadGraph Quad
q = RDFGraph -> [Either String Quad] -> [Result]
go (Maybe IRI -> [Triple] -> RDFGraph
RDFGraph Maybe IRI
gl (Quad -> Triple
quadTriple Quad
qTriple -> [Triple] -> [Triple]
forall a. a -> [a] -> [a]
:[Triple]
ts)) [Either String Quad]
qs
| Bool
otherwise = RDFGraph -> Result
forall a b. b -> Either a b
Right RDFGraph
g Result -> [Result] -> [Result]
forall a. a -> [a] -> [a]
: RDFGraph -> [Either String Quad] -> [Result]
go (Maybe IRI -> [Triple] -> RDFGraph
RDFGraph (Quad -> Maybe IRI
quadGraph Quad
q)
[Quad -> Triple
quadTriple Quad
q]) [Either String Quad]
qs
parseTriple :: A.Parser Triple
parseTriple :: Parser Triple
parseTriple = Subject -> Predicate -> Object -> Triple
Triple (Subject -> Predicate -> Object -> Triple)
-> Parser Text Subject
-> Parser Text (Predicate -> Object -> Triple)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser Text Subject
parseSubject Parser Text Subject -> Parser Text () -> Parser Text Subject
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
A.skipSpace)
Parser Text (Predicate -> Object -> Triple)
-> Parser Text Predicate -> Parser Text (Object -> Triple)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Parser Text Predicate
parsePredicate Parser Text Predicate -> Parser Text () -> Parser Text Predicate
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
A.skipSpace)
Parser Text (Object -> Triple)
-> Parser Text Object -> Parser Triple
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text Object
parseObject
parseQuad :: A.Parser Quad
parseQuad :: Parser Quad
parseQuad = Triple -> Maybe IRI -> Quad
Quad (Triple -> Maybe IRI -> Quad)
-> Parser Triple -> Parser Text (Maybe IRI -> Quad)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Triple
parseTriple
Parser Text (Maybe IRI -> Quad)
-> Parser Text (Maybe IRI) -> Parser Quad
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Parser Text ()
A.skipSpace Parser Text ()
-> Parser Text (Maybe IRI) -> Parser Text (Maybe IRI)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Text (Maybe IRI)
parseGraphLabel) Parser Text (Maybe IRI)
-> Parser Text Char -> Parser Text (Maybe IRI)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*
(Parser Text ()
A.skipSpace Parser Text () -> Parser Text Char -> Parser Text Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Char -> Parser Text Char
A.char Char
'.'))
parseQuadLine :: A.Parser Quad
parseQuadLine :: Parser Quad
parseQuadLine = Parser Quad
parseQuad Parser Quad -> Parser Text Char -> Parser Quad
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Text Char
A.char Char
'\n'