module Toml.Codec.Code
(
decode
, decodeExact
, decodeValidation
, decodeFileEither
, decodeFile
, decodeFileExact
, encode
, encodeToFile
, runTomlCodec
, execTomlCodec
) where
import Control.Exception (throwIO)
import Control.Monad.IO.Class (MonadIO (..))
import Data.Text (Text)
import Validation (Validation (..), validationToEither)
import Toml.Codec.Error (LoadTomlException (..), TomlDecodeError (..), prettyTomlDecodeErrors)
import Toml.Codec.Types (Codec (..), TomlCodec, TomlState (..))
import Toml.Parser (parse)
import Toml.Type (TOML (..), tomlDiff)
import Toml.Type.Printer (pretty)
import qualified Data.Text.IO as TIO
decodeValidation :: TomlCodec a -> Text -> Validation [TomlDecodeError] a
decodeValidation :: forall a. TomlCodec a -> Text -> Validation [TomlDecodeError] a
decodeValidation TomlCodec a
codec Text
text = case Text -> Either TomlParseError TOML
parse Text
text of
Left TomlParseError
err -> [TomlDecodeError] -> Validation [TomlDecodeError] a
forall e a. e -> Validation e a
Failure [TomlParseError -> TomlDecodeError
ParseError TomlParseError
err]
Right TOML
toml -> TomlCodec a -> TOML -> Validation [TomlDecodeError] a
forall a. TomlCodec a -> TOML -> Validation [TomlDecodeError] a
runTomlCodec TomlCodec a
codec TOML
toml
decode :: TomlCodec a -> Text -> Either [TomlDecodeError] a
decode :: forall a. TomlCodec a -> Text -> Either [TomlDecodeError] a
decode TomlCodec a
codec = Validation [TomlDecodeError] a -> Either [TomlDecodeError] a
forall e a. Validation e a -> Either e a
validationToEither (Validation [TomlDecodeError] a -> Either [TomlDecodeError] a)
-> (Text -> Validation [TomlDecodeError] a)
-> Text
-> Either [TomlDecodeError] a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TomlCodec a -> Text -> Validation [TomlDecodeError] a
forall a. TomlCodec a -> Text -> Validation [TomlDecodeError] a
decodeValidation TomlCodec a
codec
decodeExact :: TomlCodec a -> Text -> Either [TomlDecodeError] a
decodeExact :: forall a. TomlCodec a -> Text -> Either [TomlDecodeError] a
decodeExact TomlCodec a
codec Text
text = case Text -> Either TomlParseError TOML
parse Text
text of
Left TomlParseError
err -> [TomlDecodeError] -> Either [TomlDecodeError] a
forall a b. a -> Either a b
Left [TomlParseError -> TomlDecodeError
ParseError TomlParseError
err]
Right TOML
toml -> case TomlCodec a -> TOML -> Validation [TomlDecodeError] a
forall a. TomlCodec a -> TOML -> Validation [TomlDecodeError] a
runTomlCodec TomlCodec a
codec TOML
toml of
Failure [TomlDecodeError]
errs -> [TomlDecodeError] -> Either [TomlDecodeError] a
forall a b. a -> Either a b
Left [TomlDecodeError]
errs
Success a
a ->
let tomlExpected :: TOML
tomlExpected = TomlCodec a -> a -> TOML
forall a. TomlCodec a -> a -> TOML
execTomlCodec TomlCodec a
codec a
a
aDiff :: TOML
aDiff = TOML -> TOML -> TOML
tomlDiff TOML
toml TOML
tomlExpected in
if TOML
aDiff TOML -> TOML -> Bool
forall a. Eq a => a -> a -> Bool
== TOML
forall a. Monoid a => a
mempty
then a -> Either [TomlDecodeError] a
forall a b. b -> Either a b
Right a
a
else [TomlDecodeError] -> Either [TomlDecodeError] a
forall a b. a -> Either a b
Left [TOML -> TomlDecodeError
NotExactDecode TOML
aDiff]
decodeFileValidation
:: forall a m . (MonadIO m)
=> TomlCodec a
-> FilePath
-> m (Validation [TomlDecodeError] a)
decodeFileValidation :: forall a (m :: * -> *).
MonadIO m =>
TomlCodec a -> FilePath -> m (Validation [TomlDecodeError] a)
decodeFileValidation TomlCodec a
codec = (Text -> Validation [TomlDecodeError] a)
-> m Text -> m (Validation [TomlDecodeError] a)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TomlCodec a -> Text -> Validation [TomlDecodeError] a
forall a. TomlCodec a -> Text -> Validation [TomlDecodeError] a
decodeValidation TomlCodec a
codec) (m Text -> m (Validation [TomlDecodeError] a))
-> (FilePath -> m Text)
-> FilePath
-> m (Validation [TomlDecodeError] a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO Text -> m Text
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> m Text) -> (FilePath -> IO Text) -> FilePath -> m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO Text
TIO.readFile
decodeFileEither
:: forall a m . (MonadIO m)
=> TomlCodec a
-> FilePath
-> m (Either [TomlDecodeError] a)
decodeFileEither :: forall a (m :: * -> *).
MonadIO m =>
TomlCodec a -> FilePath -> m (Either [TomlDecodeError] a)
decodeFileEither TomlCodec a
codec = (Validation [TomlDecodeError] a -> Either [TomlDecodeError] a)
-> m (Validation [TomlDecodeError] a)
-> m (Either [TomlDecodeError] a)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Validation [TomlDecodeError] a -> Either [TomlDecodeError] a
forall e a. Validation e a -> Either e a
validationToEither (m (Validation [TomlDecodeError] a)
-> m (Either [TomlDecodeError] a))
-> (FilePath -> m (Validation [TomlDecodeError] a))
-> FilePath
-> m (Either [TomlDecodeError] a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TomlCodec a -> FilePath -> m (Validation [TomlDecodeError] a)
forall a (m :: * -> *).
MonadIO m =>
TomlCodec a -> FilePath -> m (Validation [TomlDecodeError] a)
decodeFileValidation TomlCodec a
codec
decodeFileExact
:: forall a m . (MonadIO m)
=> TomlCodec a
-> FilePath
-> m (Either [TomlDecodeError] a)
decodeFileExact :: forall a (m :: * -> *).
MonadIO m =>
TomlCodec a -> FilePath -> m (Either [TomlDecodeError] a)
decodeFileExact TomlCodec a
codec = (Text -> Either [TomlDecodeError] a)
-> m Text -> m (Either [TomlDecodeError] a)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TomlCodec a -> Text -> Either [TomlDecodeError] a
forall a. TomlCodec a -> Text -> Either [TomlDecodeError] a
decodeExact TomlCodec a
codec) (m Text -> m (Either [TomlDecodeError] a))
-> (FilePath -> m Text)
-> FilePath
-> m (Either [TomlDecodeError] a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO Text -> m Text
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> m Text) -> (FilePath -> IO Text) -> FilePath -> m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO Text
TIO.readFile
decodeFile :: forall a m . (MonadIO m) => TomlCodec a -> FilePath -> m a
decodeFile :: forall a (m :: * -> *). MonadIO m => TomlCodec a -> FilePath -> m a
decodeFile TomlCodec a
codec FilePath
filePath = TomlCodec a -> FilePath -> m (Either [TomlDecodeError] a)
forall a (m :: * -> *).
MonadIO m =>
TomlCodec a -> FilePath -> m (Either [TomlDecodeError] a)
decodeFileEither TomlCodec a
codec FilePath
filePath m (Either [TomlDecodeError] a)
-> (Either [TomlDecodeError] a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either [TomlDecodeError] a -> m a
errorWhenLeft
where
errorWhenLeft :: Either [TomlDecodeError] a -> m a
errorWhenLeft :: Either [TomlDecodeError] a -> m a
errorWhenLeft (Left [TomlDecodeError]
errs) =
IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
(IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ LoadTomlException -> IO a
forall e a. Exception e => e -> IO a
throwIO
(LoadTomlException -> IO a) -> LoadTomlException -> IO a
forall a b. (a -> b) -> a -> b
$ FilePath -> Text -> LoadTomlException
LoadTomlException FilePath
filePath
(Text -> LoadTomlException) -> Text -> LoadTomlException
forall a b. (a -> b) -> a -> b
$ [TomlDecodeError] -> Text
prettyTomlDecodeErrors [TomlDecodeError]
errs
errorWhenLeft (Right a
pc) = a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
pc
encode :: TomlCodec a -> a -> Text
encode :: forall a. TomlCodec a -> a -> Text
encode TomlCodec a
codec a
obj = TOML -> Text
pretty (TOML -> Text) -> TOML -> Text
forall a b. (a -> b) -> a -> b
$ TomlCodec a -> a -> TOML
forall a. TomlCodec a -> a -> TOML
execTomlCodec TomlCodec a
codec a
obj
encodeToFile :: forall a m . (MonadIO m) => TomlCodec a -> FilePath -> a -> m Text
encodeToFile :: forall a (m :: * -> *).
MonadIO m =>
TomlCodec a -> FilePath -> a -> m Text
encodeToFile TomlCodec a
codec FilePath
filePath a
obj = Text
content Text -> m () -> m Text
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (FilePath -> Text -> IO ()
TIO.writeFile FilePath
filePath Text
content)
where
content :: Text
content :: Text
content = TomlCodec a -> a -> Text
forall a. TomlCodec a -> a -> Text
encode TomlCodec a
codec a
obj
runTomlCodec :: TomlCodec a -> TOML -> Validation [TomlDecodeError] a
runTomlCodec :: forall a. TomlCodec a -> TOML -> Validation [TomlDecodeError] a
runTomlCodec = Codec a a -> TomlEnv a
forall i o. Codec i o -> TomlEnv o
codecRead
execTomlCodec :: TomlCodec a -> a -> TOML
execTomlCodec :: forall a. TomlCodec a -> a -> TOML
execTomlCodec TomlCodec a
codec a
obj = (Maybe a, TOML) -> TOML
forall a b. (a, b) -> b
snd ((Maybe a, TOML) -> TOML) -> (Maybe a, TOML) -> TOML
forall a b. (a -> b) -> a -> b
$ TomlState a -> TOML -> (Maybe a, TOML)
forall a. TomlState a -> TOML -> (Maybe a, TOML)
unTomlState (TomlCodec a -> a -> TomlState a
forall i o. Codec i o -> i -> TomlState o
codecWrite TomlCodec a
codec a
obj) TOML
forall a. Monoid a => a
mempty