Copyright | (C) 2015 Oleg Grenrus |
---|---|
License | BSD3 |
Maintainer | Oleg Grenrus <oleg.grenrus@iki.fi> |
Safe Haskell | None |
Language | Haskell2010 |
Data.Binary.Tagged
Description
Structurally tag binary serialisation stream.
Say you have:
data Record = Record { _recordFields :: HM.HashMap Text (Integer, ByteString) , _recordEnabled :: Bool } deriving (Eq, Show, Generic) instance Binary Record instance HasStructuralInfo Record instance HasSemanticVersion Record
then you can serialise and deserialise Record
values with a structure tag by simply
encodeTaggedFile "cachefile" record decodeTaggedFile "cachefile" :: IO Record
If structure of Record
changes in between, deserialisation will fail early.
Synopsis
- newtype BinaryTagged (v :: k) a = BinaryTagged {
- unBinaryTagged :: a
- type BinaryTagged' a = BinaryTagged (SemanticVersion a) a
- binaryTag :: Proxy v -> a -> BinaryTagged v a
- binaryTag' :: HasSemanticVersion a => a -> BinaryTagged' a
- binaryUntag :: Proxy v -> BinaryTagged v a -> a
- binaryUntag' :: HasSemanticVersion a => BinaryTagged' a -> a
- data StructuralInfo
- = NominalType String
- | NominalNewtype String StructuralInfo
- | StructuralInfo String [[StructuralInfo]]
- taggedEncode :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => a -> ByteString
- taggedDecode :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => ByteString -> a
- taggedDecodeOrFail :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => ByteString -> Either (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
- taggedEncodeFile :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => FilePath -> a -> IO ()
- taggedDecodeFile :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => FilePath -> IO a
- taggedDecodeFileOrFail :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => FilePath -> IO (Either (ByteOffset, String) a)
- class HasStructuralInfo a where
- structuralInfo :: Proxy a -> StructuralInfo
- class KnownNat (SemanticVersion a) => HasSemanticVersion (a :: *) where
- type SemanticVersion a :: Nat
- type Version = Word32
- type Interleave (n :: Nat) (m :: Nat) = SumUpTo (n + m) + m
- type SumUpTo (n :: Nat) = Div2 (n * (n + 1))
- type family Div2 (n :: Nat) :: Nat where ...
- ghcStructuralInfo :: (Generic a, All2 HasStructuralInfo (GCode a), GDatatypeInfo a, SListI2 (GCode a)) => Proxy a -> StructuralInfo
- ghcNominalType :: (Generic a, GDatatypeInfo a) => Proxy a -> StructuralInfo
- ghcStructuralInfo1 :: forall f a. (Generic1 f, GDatatypeInfo (f a), HasStructuralInfo a) => Proxy (f a) -> StructuralInfo
- sopStructuralInfo :: forall a. (Generic a, HasDatatypeInfo a, All2 HasStructuralInfo (Code a)) => Proxy a -> StructuralInfo
- sopNominalType :: forall a. (Generic a, HasDatatypeInfo a) => Proxy a -> StructuralInfo
- sopStructuralInfo1 :: forall f a. (Generic (f a), HasDatatypeInfo (f a), HasStructuralInfo a) => Proxy (f a) -> StructuralInfo
- sopStructuralInfoS :: forall xss. (All2 HasStructuralInfo xss, SListI2 xss) => DatatypeInfo xss -> StructuralInfo
- sopNominalTypeS :: DatatypeInfo xss -> StructuralInfo
- sopStructuralInfo1S :: StructuralInfo -> DatatypeInfo xss -> StructuralInfo
- structuralInfoSha1Digest :: StructuralInfo -> ByteString
- structuralInfoSha1ByteStringDigest :: StructuralInfo -> ByteString
Data
newtype BinaryTagged (v :: k) a Source #
Binary
serialisable class, which tries to be less error-prone to data structure changes.
Values are serialised with header consisting of version v
and hash of structuralInfo
.
Constructors
BinaryTagged | |
Fields
|
Instances
Generic1 (BinaryTagged v :: Type -> Type) Source # | |
Defined in Data.Binary.Tagged Associated Types type Rep1 (BinaryTagged v) :: k -> Type Methods from1 :: forall (a :: k). BinaryTagged v a -> Rep1 (BinaryTagged v) a to1 :: forall (a :: k). Rep1 (BinaryTagged v) a -> BinaryTagged v a | |
Monad (BinaryTagged v) Source # | |
Defined in Data.Binary.Tagged Methods (>>=) :: BinaryTagged v a -> (a -> BinaryTagged v b) -> BinaryTagged v b (>>) :: BinaryTagged v a -> BinaryTagged v b -> BinaryTagged v b return :: a -> BinaryTagged v a | |
Functor (BinaryTagged v) Source # | |
Defined in Data.Binary.Tagged Methods fmap :: (a -> b) -> BinaryTagged v a -> BinaryTagged v b (<$) :: a -> BinaryTagged v b -> BinaryTagged v a | |
Applicative (BinaryTagged v) Source # | |
Defined in Data.Binary.Tagged Methods pure :: a -> BinaryTagged v a (<*>) :: BinaryTagged v (a -> b) -> BinaryTagged v a -> BinaryTagged v b liftA2 :: (a -> b -> c) -> BinaryTagged v a -> BinaryTagged v b -> BinaryTagged v c (*>) :: BinaryTagged v a -> BinaryTagged v b -> BinaryTagged v b (<*) :: BinaryTagged v a -> BinaryTagged v b -> BinaryTagged v a | |
Foldable (BinaryTagged v) Source # | |
Defined in Data.Binary.Tagged Methods fold :: Monoid m => BinaryTagged v m -> m foldMap :: Monoid m => (a -> m) -> BinaryTagged v a -> m foldMap' :: Monoid m => (a -> m) -> BinaryTagged v a -> m foldr :: (a -> b -> b) -> b -> BinaryTagged v a -> b foldr' :: (a -> b -> b) -> b -> BinaryTagged v a -> b foldl :: (b -> a -> b) -> b -> BinaryTagged v a -> b foldl' :: (b -> a -> b) -> b -> BinaryTagged v a -> b foldr1 :: (a -> a -> a) -> BinaryTagged v a -> a foldl1 :: (a -> a -> a) -> BinaryTagged v a -> a toList :: BinaryTagged v a -> [a] null :: BinaryTagged v a -> Bool length :: BinaryTagged v a -> Int elem :: Eq a => a -> BinaryTagged v a -> Bool maximum :: Ord a => BinaryTagged v a -> a minimum :: Ord a => BinaryTagged v a -> a sum :: Num a => BinaryTagged v a -> a product :: Num a => BinaryTagged v a -> a | |
Traversable (BinaryTagged v) Source # | |
Defined in Data.Binary.Tagged Methods traverse :: Applicative f => (a -> f b) -> BinaryTagged v a -> f (BinaryTagged v b) sequenceA :: Applicative f => BinaryTagged v (f a) -> f (BinaryTagged v a) mapM :: Monad m => (a -> m b) -> BinaryTagged v a -> m (BinaryTagged v b) sequence :: Monad m => BinaryTagged v (m a) -> m (BinaryTagged v a) | |
Eq a => Eq (BinaryTagged v a) Source # | |
Defined in Data.Binary.Tagged Methods (==) :: BinaryTagged v a -> BinaryTagged v a -> Bool (/=) :: BinaryTagged v a -> BinaryTagged v a -> Bool | |
Ord a => Ord (BinaryTagged v a) Source # | |
Defined in Data.Binary.Tagged Methods compare :: BinaryTagged v a -> BinaryTagged v a -> Ordering (<) :: BinaryTagged v a -> BinaryTagged v a -> Bool (<=) :: BinaryTagged v a -> BinaryTagged v a -> Bool (>) :: BinaryTagged v a -> BinaryTagged v a -> Bool (>=) :: BinaryTagged v a -> BinaryTagged v a -> Bool max :: BinaryTagged v a -> BinaryTagged v a -> BinaryTagged v a min :: BinaryTagged v a -> BinaryTagged v a -> BinaryTagged v a | |
Read a => Read (BinaryTagged v a) Source # | |
Defined in Data.Binary.Tagged Methods readsPrec :: Int -> ReadS (BinaryTagged v a) readList :: ReadS [BinaryTagged v a] readPrec :: ReadPrec (BinaryTagged v a) readListPrec :: ReadPrec [BinaryTagged v a] | |
Show a => Show (BinaryTagged v a) Source # | |
Defined in Data.Binary.Tagged Methods showsPrec :: Int -> BinaryTagged v a -> ShowS show :: BinaryTagged v a -> String showList :: [BinaryTagged v a] -> ShowS | |
Generic (BinaryTagged v a) Source # | |
Defined in Data.Binary.Tagged Associated Types type Rep (BinaryTagged v a) :: Type -> Type Methods from :: BinaryTagged v a -> Rep (BinaryTagged v a) x to :: Rep (BinaryTagged v a) x -> BinaryTagged v a | |
Semigroup a => Semigroup (BinaryTagged v a) Source # | |
Defined in Data.Binary.Tagged Methods (<>) :: BinaryTagged v a -> BinaryTagged v a -> BinaryTagged v a sconcat :: NonEmpty (BinaryTagged v a) -> BinaryTagged v a stimes :: Integral b => b -> BinaryTagged v a -> BinaryTagged v a | |
Monoid a => Monoid (BinaryTagged v a) Source # | |
Defined in Data.Binary.Tagged Methods mempty :: BinaryTagged v a mappend :: BinaryTagged v a -> BinaryTagged v a -> BinaryTagged v a mconcat :: [BinaryTagged v a] -> BinaryTagged v a | |
(Binary a, HasStructuralInfo a, KnownNat v) => Binary (BinaryTagged v a) Source # | Version and structure hash are prepended to serialised stream |
Defined in Data.Binary.Tagged Methods put :: BinaryTagged v a -> Put get :: Get (BinaryTagged v a) putList :: [BinaryTagged v a] -> Put | |
type Rep1 (BinaryTagged v :: Type -> Type) Source # | |
Defined in Data.Binary.Tagged type Rep1 (BinaryTagged v :: Type -> Type) = D1 ('MetaData "BinaryTagged" "Data.Binary.Tagged" "binary-tagged-0.2-LQbnt56jj6fIEZTMDu7y8p" 'True) (C1 ('MetaCons "BinaryTagged" 'PrefixI 'True) (S1 ('MetaSel ('Just "unBinaryTagged") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1)) | |
type Rep (BinaryTagged v a) Source # | |
Defined in Data.Binary.Tagged type Rep (BinaryTagged v a) = D1 ('MetaData "BinaryTagged" "Data.Binary.Tagged" "binary-tagged-0.2-LQbnt56jj6fIEZTMDu7y8p" 'True) (C1 ('MetaCons "BinaryTagged" 'PrefixI 'True) (S1 ('MetaSel ('Just "unBinaryTagged") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a))) |
type BinaryTagged' a = BinaryTagged (SemanticVersion a) a Source #
binaryTag :: Proxy v -> a -> BinaryTagged v a Source #
binaryTag' :: HasSemanticVersion a => a -> BinaryTagged' a Source #
binaryUntag :: Proxy v -> BinaryTagged v a -> a Source #
binaryUntag' :: HasSemanticVersion a => BinaryTagged' a -> a Source #
data StructuralInfo Source #
Data type structure, with (some) nominal information.
Constructors
NominalType String | |
NominalNewtype String StructuralInfo | |
StructuralInfo String [[StructuralInfo]] |
Instances
Serialisation
taggedEncode :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => a -> ByteString Source #
Tagged version of encode
taggedDecode :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => ByteString -> a Source #
Tagged version of decode
taggedDecodeOrFail :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => ByteString -> Either (ByteString, ByteOffset, String) (ByteString, ByteOffset, a) Source #
Tagged version of decodeOrFail
IO functions for serialisation
taggedEncodeFile :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => FilePath -> a -> IO () Source #
Tagged version of encodeFile
taggedDecodeFile :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => FilePath -> IO a Source #
Tagged version of decodeFile
taggedDecodeFileOrFail :: forall a. (HasStructuralInfo a, HasSemanticVersion a, Binary a) => FilePath -> IO (Either (ByteOffset, String) a) Source #
Tagged version of decodeFileOrFail
Class
class HasStructuralInfo a where Source #
Type class providing StructuralInfo
for each data type.
For regular non-recursive ADTs HasStructuralInfo
can be derived generically.
data Record = Record { a :: Int, b :: Bool, c :: [Char] } deriving (Generic) instance hasStructuralInfo Record
For stable types, you can provide only type name
instance HasStructuralInfo Int where structuralInfo = ghcNominalType -- infer name from Generic information instance HasStructuralInfo Integer where structuralInfo _ = NominalType "Integer"
Recursive type story is a bit sad atm. If the type structure is stable, you can do:
instance HasStructuralInfo a => HasStructuralInfo [a] where structuralInfo = ghcStructuralInfo1
Minimal complete definition
Nothing
Methods
structuralInfo :: Proxy a -> StructuralInfo Source #
default structuralInfo :: (Generic a, All2 HasStructuralInfo (GCode a), GDatatypeInfo a, SListI2 (GCode a)) => Proxy a -> StructuralInfo Source #
Instances
class KnownNat (SemanticVersion a) => HasSemanticVersion (a :: *) Source #
A helper type family for encodeTaggedFile
and decodeTaggedFile
.
The default definition is SemanticVersion
a = 0
Instances
Type level calculations
type Interleave (n :: Nat) (m :: Nat) = SumUpTo (n + m) + m Source #
Interleaving
3 | 9 . . . . 2 | 5 8 . . . 1 | 2 4 7 11 . 0 | 0 1 3 6 10 ----------------- 0 1 2 3 4
This can be calculated by f x y = sum ([0..x+y]) + y
Generic derivation
GHC
ghcStructuralInfo :: (Generic a, All2 HasStructuralInfo (GCode a), GDatatypeInfo a, SListI2 (GCode a)) => Proxy a -> StructuralInfo Source #
ghcNominalType :: (Generic a, GDatatypeInfo a) => Proxy a -> StructuralInfo Source #
ghcStructuralInfo1 :: forall f a. (Generic1 f, GDatatypeInfo (f a), HasStructuralInfo a) => Proxy (f a) -> StructuralInfo Source #
SOP
sopStructuralInfo :: forall a. (Generic a, HasDatatypeInfo a, All2 HasStructuralInfo (Code a)) => Proxy a -> StructuralInfo Source #
sopNominalType :: forall a. (Generic a, HasDatatypeInfo a) => Proxy a -> StructuralInfo Source #
sopStructuralInfo1 :: forall f a. (Generic (f a), HasDatatypeInfo (f a), HasStructuralInfo a) => Proxy (f a) -> StructuralInfo Source #
SOP direct
sopStructuralInfoS :: forall xss. (All2 HasStructuralInfo xss, SListI2 xss) => DatatypeInfo xss -> StructuralInfo Source #
sopNominalTypeS :: DatatypeInfo xss -> StructuralInfo Source #
sopStructuralInfo1S :: StructuralInfo -> DatatypeInfo xss -> StructuralInfo Source #
Hash
structuralInfoSha1Digest :: StructuralInfo -> ByteString Source #
structuralInfoSha1ByteStringDigest :: StructuralInfo -> ByteString Source #
Deprecated: Use structuralInfoSha1Digest directly