module Data.Svfactor.Parse (
parseSv
, parseSv'
, parseSvFromFile
, parseSvFromFile'
, separatedValues
, module Data.Svfactor.Parse.Options
, SvParser (..)
, trifecta
, trifectaResultToEither
, attoparsecByteString
, attoparsecText
) where
import Control.Applicative ((<$>))
import Control.Lens (view)
import Control.Monad.IO.Class (MonadIO, liftIO)
import qualified Data.Attoparsec.ByteString as BS (parseOnly)
import qualified Data.Attoparsec.Text as Text (parseOnly)
import Data.Bifunctor (first)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.Monoid (mempty)
import Data.Text (Text)
import qualified Data.Text.IO as Text
import qualified Text.Trifecta as Trifecta
import Data.Svfactor.Syntax.Sv (Sv)
import Data.Svfactor.Parse.Internal (separatedValues)
import Data.Svfactor.Parse.Options
parseSv :: ParseOptions ByteString -> ByteString -> Either ByteString (Sv ByteString)
parseSv = parseSv' trifecta
parseSv' :: SvParser s -> ParseOptions s -> s -> Either s (Sv s)
parseSv' svp opts s =
let enc = view encodeString opts
in first enc $ runSvParser svp opts s
parseSvFromFile :: MonadIO m => ParseOptions ByteString -> FilePath -> m (Either ByteString (Sv ByteString))
parseSvFromFile = parseSvFromFile' trifecta
parseSvFromFile' :: MonadIO m => SvParser s -> ParseOptions s -> FilePath -> m (Either s (Sv s))
parseSvFromFile' svp opts fp =
let enc = view encodeString opts
in liftIO (first enc <$> runSvParserFromFile svp opts fp)
data SvParser s = SvParser
{ runSvParser :: ParseOptions s -> s -> Either String (Sv s)
, runSvParserFromFile :: ParseOptions s -> FilePath -> IO (Either String (Sv s))
}
trifecta :: SvParser ByteString
trifecta = SvParser
{ runSvParser = \opts bs -> trifectaResultToEither $ Trifecta.parseByteString (separatedValues opts) mempty bs
, runSvParserFromFile = \opts fp -> trifectaResultToEither <$> Trifecta.parseFromFileEx (separatedValues opts) fp
}
attoparsecByteString :: SvParser ByteString
attoparsecByteString = SvParser
{ runSvParser = \opts bs -> BS.parseOnly (separatedValues opts) bs
, runSvParserFromFile = \opts fp -> BS.parseOnly (separatedValues opts) <$> BS.readFile fp
}
attoparsecText :: SvParser Text
attoparsecText = SvParser
{ runSvParser = \opts t -> Text.parseOnly (separatedValues opts) t
, runSvParserFromFile = \opts fp -> Text.parseOnly (separatedValues opts) <$> Text.readFile fp
}
trifectaResultToEither :: Trifecta.Result a -> Either String a
trifectaResultToEither result = case result of
Trifecta.Success a -> Right a
Trifecta.Failure e -> Left . show . Trifecta._errDoc $ e