module Data.SafeCopy.Store.Encode where
import Data.ByteString (ByteString)
import Data.Monoid
import Data.Store
import Data.Store.Core
data Encode a = Encode !Int !(Poke ()) !a
instance Monoid a => Monoid (Encode a) where
mempty = Encode 0 (Poke $ \_ offset -> pure (offset, ())) mempty
(Encode len1 f1 a1) `mappend` (Encode len2 f2 a2) = Encode (len1 + len2) (f1 *> f2) (a1 <> a2)
instance Functor Encode where
fmap f (Encode l p a) = Encode l p (f a)
instance Applicative Encode where
pure = Encode 0 (Poke $ \_ offset -> pure (offset, ()))
(Encode len1 f1 af) <*> (Encode len2 f2 b) = Encode (len1 + len2) (f1 *> f2) (af b)
instance Monad Encode where
return = pure
(Encode len1 f1 a) >>= ef = case ef a of
Encode len2 f2 b -> Encode (len1 + len2) (f1 *> f2) b
getEncodeLen :: Encode a -> Int
getEncodeLen (Encode len _ _) = len
runEncode :: Encode a -> ByteString
runEncode (Encode len f _) = unsafeEncodeWith f len
pokeE :: forall a . Store a => a -> Encode a
pokeE v = Encode len (poke v) v
where
len = case (size :: Size a) of
VarSize sf -> sf v
ConstSize cs -> cs