{-# 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 bs0 :: 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 _bs :: ByteString
_bs (CBOR.Read.Done _ _ x :: b
x) = b -> ST s b
forall (m :: * -> *) a. Monad m => a -> m a
return b
x
supplyAllInput bs :: ByteString
bs (CBOR.Read.Partial k :: Maybe ByteString -> ST s (IDecode s b)
k) =
case ByteString
bs of
BS.Chunk chunk :: ByteString
chunk bs' :: 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'
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 _ (CBOR.Read.Fail _ _ exn :: 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 bs0 :: 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 _bs :: ByteString
_bs (CBOR.Read.Done _ _ x :: 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 bs :: ByteString
bs (CBOR.Read.Partial k :: Maybe ByteString -> ST s (IDecode s b)
k) =
case ByteString
bs of
BS.Chunk chunk :: ByteString
chunk bs' :: 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'
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 _ (CBOR.Read.Fail _ _ exn :: 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 hnd :: Handle
hnd x :: 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 fname :: FilePath
fname x :: 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
$ \hnd :: 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 fname :: 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
$ \hnd :: 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 err :: DeserialiseFailure
err -> DeserialiseFailure -> IO a
forall e a. Exception e => e -> IO a
throwIO DeserialiseFailure
err
Right x :: a
x -> a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x