{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
module Codec.Serialise
(
serialise
, deserialise
, deserialiseOrFail
, CBOR.Read.DeserialiseFailure(..)
, serialiseIncremental
, deserialiseIncremental
, CBOR.Read.IDecode(..)
, Serialise(..)
, writeFileSerialise
, readFileDeserialise
, hPutSerialise
) where
import Control.Monad.ST
import System.IO (Handle, IOMode (..), withFile)
import Control.Exception (throw, throwIO)
import qualified Data.ByteString.Builder as BS
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Lazy.Internal as BS
import Codec.Serialise.Class
import qualified Codec.CBOR.Read as CBOR.Read
import qualified Codec.CBOR.Write as CBOR.Write
serialiseIncremental :: Serialise a => a -> BS.Builder
serialiseIncremental :: a -> Builder
serialiseIncremental = Encoding -> Builder
CBOR.Write.toBuilder (Encoding -> Builder) -> (a -> Encoding) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Encoding
forall a. Serialise a => a -> Encoding
encode
deserialiseIncremental :: Serialise a => ST s (CBOR.Read.IDecode s a)
deserialiseIncremental :: ST s (IDecode s a)
deserialiseIncremental = Decoder s a -> ST s (IDecode s a)
forall s a. Decoder s a -> ST s (IDecode s a)
CBOR.Read.deserialiseIncremental Decoder s a
forall a s. Serialise a => Decoder s a
decode
serialise :: Serialise a => a -> BS.ByteString
serialise :: a -> ByteString
serialise = Encoding -> ByteString
CBOR.Write.toLazyByteString (Encoding -> ByteString) -> (a -> Encoding) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Encoding
forall a. Serialise a => a -> Encoding
encode
deserialise :: Serialise a => BS.ByteString -> a
deserialise :: ByteString -> a
deserialise ByteString
bs0 =
(forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST (ByteString -> IDecode s a -> ST s a
forall s b. ByteString -> IDecode s b -> ST s b
supplyAllInput ByteString
bs0 (IDecode s a -> ST s a) -> ST s (IDecode s a) -> ST s a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ST s (IDecode s a)
forall a s. Serialise a => ST s (IDecode s a)
deserialiseIncremental)
where
supplyAllInput :: ByteString -> IDecode s b -> ST s b
supplyAllInput ByteString
_bs (CBOR.Read.Done ByteString
_ ByteOffset
_ b
x) = b -> ST s b
forall (m :: * -> *) a. Monad m => a -> m a
return b
x
supplyAllInput ByteString
bs (CBOR.Read.Partial Maybe ByteString -> ST s (IDecode s b)
k) =
case ByteString
bs of
BS.Chunk ByteString
chunk ByteString
bs' -> Maybe ByteString -> ST s (IDecode s b)
k (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
chunk) ST s (IDecode s b) -> (IDecode s b -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> IDecode s b -> ST s b
supplyAllInput ByteString
bs'
ByteString
BS.Empty -> Maybe ByteString -> ST s (IDecode s b)
k Maybe ByteString
forall a. Maybe a
Nothing ST s (IDecode s b) -> (IDecode s b -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> IDecode s b -> ST s b
supplyAllInput ByteString
BS.Empty
supplyAllInput ByteString
_ (CBOR.Read.Fail ByteString
_ ByteOffset
_ DeserialiseFailure
exn) = DeserialiseFailure -> ST s b
forall a e. Exception e => e -> a
throw DeserialiseFailure
exn
deserialiseOrFail :: Serialise a => BS.ByteString -> Either CBOR.Read.DeserialiseFailure a
deserialiseOrFail :: ByteString -> Either DeserialiseFailure a
deserialiseOrFail ByteString
bs0 =
(forall s. ST s (Either DeserialiseFailure a))
-> Either DeserialiseFailure a
forall a. (forall s. ST s a) -> a
runST (ByteString -> IDecode s a -> ST s (Either DeserialiseFailure a)
forall s b.
ByteString -> IDecode s b -> ST s (Either DeserialiseFailure b)
supplyAllInput ByteString
bs0 (IDecode s a -> ST s (Either DeserialiseFailure a))
-> ST s (IDecode s a) -> ST s (Either DeserialiseFailure a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ST s (IDecode s a)
forall a s. Serialise a => ST s (IDecode s a)
deserialiseIncremental)
where
supplyAllInput :: ByteString -> IDecode s b -> ST s (Either DeserialiseFailure b)
supplyAllInput ByteString
_bs (CBOR.Read.Done ByteString
_ ByteOffset
_ b
x) = Either DeserialiseFailure b -> ST s (Either DeserialiseFailure b)
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> Either DeserialiseFailure b
forall a b. b -> Either a b
Right b
x)
supplyAllInput ByteString
bs (CBOR.Read.Partial Maybe ByteString -> ST s (IDecode s b)
k) =
case ByteString
bs of
BS.Chunk ByteString
chunk ByteString
bs' -> Maybe ByteString -> ST s (IDecode s b)
k (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
chunk) ST s (IDecode s b)
-> (IDecode s b -> ST s (Either DeserialiseFailure b))
-> ST s (Either DeserialiseFailure b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> IDecode s b -> ST s (Either DeserialiseFailure b)
supplyAllInput ByteString
bs'
ByteString
BS.Empty -> Maybe ByteString -> ST s (IDecode s b)
k Maybe ByteString
forall a. Maybe a
Nothing ST s (IDecode s b)
-> (IDecode s b -> ST s (Either DeserialiseFailure b))
-> ST s (Either DeserialiseFailure b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> IDecode s b -> ST s (Either DeserialiseFailure b)
supplyAllInput ByteString
BS.Empty
supplyAllInput ByteString
_ (CBOR.Read.Fail ByteString
_ ByteOffset
_ DeserialiseFailure
exn) = Either DeserialiseFailure b -> ST s (Either DeserialiseFailure b)
forall (m :: * -> *) a. Monad m => a -> m a
return (DeserialiseFailure -> Either DeserialiseFailure b
forall a b. a -> Either a b
Left DeserialiseFailure
exn)
hPutSerialise :: Serialise a
=> Handle
-> a
-> IO ()
hPutSerialise :: Handle -> a -> IO ()
hPutSerialise Handle
hnd a
x = Handle -> ByteString -> IO ()
BS.hPut Handle
hnd (a -> ByteString
forall a. Serialise a => a -> ByteString
serialise a
x)
writeFileSerialise :: Serialise a
=> FilePath
-> a
-> IO ()
writeFileSerialise :: FilePath -> a -> IO ()
writeFileSerialise FilePath
fname a
x =
FilePath -> IOMode -> (Handle -> IO ()) -> IO ()
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFile FilePath
fname IOMode
WriteMode ((Handle -> IO ()) -> IO ()) -> (Handle -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Handle
hnd -> Handle -> a -> IO ()
forall a. Serialise a => Handle -> a -> IO ()
hPutSerialise Handle
hnd a
x
readFileDeserialise :: Serialise a
=> FilePath
-> IO a
readFileDeserialise :: FilePath -> IO a
readFileDeserialise FilePath
fname =
FilePath -> IOMode -> (Handle -> IO a) -> IO a
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFile FilePath
fname IOMode
ReadMode ((Handle -> IO a) -> IO a) -> (Handle -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \Handle
hnd -> do
ByteString
input <- Handle -> IO ByteString
BS.hGetContents Handle
hnd
case ByteString -> Either DeserialiseFailure a
forall a. Serialise a => ByteString -> Either DeserialiseFailure a
deserialiseOrFail ByteString
input of
Left DeserialiseFailure
err -> DeserialiseFailure -> IO a
forall e a. Exception e => e -> IO a
throwIO DeserialiseFailure
err
Right a
x -> a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x