Portability | non-portable (uses GHC extensions) |
---|---|
Maintainer | lemmih@gmail.com |
Safe Haskell | Safe-Infered |
Data.SafeCopy.SafeCopy
Description
SafeCopy extends the parsing and serialization capabilities of Data.Binary to include nested version control. Nested version control means that you can change the defintion and binary format of a type nested deep within other types without problems.
- class SafeCopy (MigrateFrom a) => Migrate a where
- type MigrateFrom a
- migrate :: MigrateFrom a -> a
- data Kind a where
- newtype Prim a = Prim {
- getPrimitive :: a
- class SafeCopy a where
- version :: Version a
- kind :: Kind a
- getCopy :: Contained (Get a)
- putCopy :: a -> Contained Put
- internalConsistency :: Consistency a
- errorTypeName :: Proxy a -> String
- constructGetterFromVersion :: SafeCopy a => Version a -> Proxy a -> Get a
- safeGet :: SafeCopy a => Get a
- getSafeGet :: forall a. SafeCopy a => Get (Get a)
- safePut :: SafeCopy a => a -> Put
- getSafePut :: forall a. SafeCopy a => PutM (a -> Put)
- extension :: (SafeCopy a, Migrate a) => Kind a
- base :: Kind a
- primitive :: Kind a
- newtype Version a = Version {}
- castVersion :: Version a -> Version b
- newtype Contained a = Contained {
- unsafeUnPack :: a
- contain :: a -> Contained a
- data Consistency a
- availableVersions :: SafeCopy a => Proxy a -> [Int32]
- validChain :: SafeCopy a => Proxy a -> Bool
- checkConsistency :: (SafeCopy a, Monad m) => Proxy a -> m b -> m b
- computeConsistency :: SafeCopy a => Proxy a -> Consistency a
- isObviouslyConsistent :: Kind a -> Bool
- proxyFromConsistency :: Consistency a -> Proxy a
- consistentFromProxy :: SafeCopy a => Proxy a -> Consistency a
- versionFromProxy :: SafeCopy a => Proxy a -> Version a
- kindFromProxy :: SafeCopy a => Proxy a -> Kind a
- data Proxy a = Proxy
- mkProxy :: a -> Proxy a
- asProxyType :: a -> Proxy a -> a
Documentation
class SafeCopy (MigrateFrom a) => Migrate a whereSource
The central mechanism for dealing with version control.
This type class specifies what data migrations can happen and how they happen.
Associated Types
type MigrateFrom a Source
This is the type we're extending. Each type capable of migration can only extend one other type.
Methods
migrate :: MigrateFrom a -> aSource
This method specifies how to migrate from the older type to the newer one. It will never be necessary to use this function manually as it all taken care of internally in the library.
The kind of a data type determines how it is tagged (if at all).
Primitives kinds (see primitive
) are not tagged with a version
id and hence cannot be extended later.
Extensions (see extension
) tells the system that there exists
a previous version of the data type which should be migrated if
needed.
There is also a default kind which is neither primitive nor is an extension of a previous type.
Wrapper for data that was saved without a version tag.
Constructors
Prim | |
Fields
|
The centerpiece of this library. Defines a version for a data type together with how it should be serialized/parsed.
Users should define instances of SafeCopy
for their types
even though getCopy
and putCopy
can't be used directly.
To serialize/parse a data type using SafeCopy
, see safeGet
and safePut
.
Methods
The version of the type.
Only used as a key so it must be unique (this is checked at run-time) but doesn't have to be sequential or continuous.
The default version is '0'.
The kind specifies how versions are dealt with. By default,
values are tagged with their version id and don't have any
previous versions. See extension
and the much less used
primitive
.
getCopy :: Contained (Get a)Source
This method defines how a value should be parsed without also worrying
about writing out the version tag. This function cannot be used directly.
One should use safeGet
, instead.
putCopy :: a -> Contained PutSource
This method defines how a value should be parsed without worrying about
previous versions or migrations. This function cannot be used directly.
One should use safeGet
, instead.
internalConsistency :: Consistency aSource
Internal function that should not be overrided.
Consistent
iff the version history is consistent
(i.e. there are no duplicate version numbers) and
the chain of migrations is valid.
This function is in the typeclass so that this
information is calculated only once during the program
lifetime, instead of everytime safeGet
or safePut
is
used.
errorTypeName :: Proxy a -> StringSource
The name of the type. This is only used in error message strings. Feel free to leave undefined in your instances.
Instances
safeGet :: SafeCopy a => Get aSource
Parse a version tagged data type and then migrate it to the desired type. Any serialized value has been extended by the return type can be parsed.
getSafeGet :: forall a. SafeCopy a => Get (Get a)Source
Parse a version tag and return the corresponding migrated parser. This is
useful when you can prove that multiple values have the same version.
See getSafePut
.
safePut :: SafeCopy a => a -> PutSource
Serialize a data type by first writing out its version tag. This is much
simpler than the corresponding safeGet
since previous versions don't
come into play.
getSafePut :: forall a. SafeCopy a => PutM (a -> Put)Source
Serialize the version tag and return the associated putter. This is useful
when serializing multiple values with the same version. See getSafeGet
.
extension :: (SafeCopy a, Migrate a) => Kind aSource
The extension kind lets the system know that there is at least one previous version of this type. A given data type can only extend a single other data type. However, it is perfectly fine to build chains of extensions. The migrations between each step is handled automatically.
A simple numeric version id.
castVersion :: Version a -> Version bSource
To ensure that no-one reads or writes values without handling versions
correct, it is necessary to restrict access to getCopy
and putCopy
.
This is where Contained
enters the picture. It allows you to put
values in to a container but not to take them out again.
Constructors
Contained | |
Fields
|
data Consistency a Source
Constructors
Consistent | |
NotConsistent String |
availableVersions :: SafeCopy a => Proxy a -> [Int32]Source
validChain :: SafeCopy a => Proxy a -> BoolSource
checkConsistency :: (SafeCopy a, Monad m) => Proxy a -> m b -> m bSource
computeConsistency :: SafeCopy a => Proxy a -> Consistency aSource
isObviouslyConsistent :: Kind a -> BoolSource
proxyFromConsistency :: Consistency a -> Proxy aSource
consistentFromProxy :: SafeCopy a => Proxy a -> Consistency aSource
versionFromProxy :: SafeCopy a => Proxy a -> Version aSource
kindFromProxy :: SafeCopy a => Proxy a -> Kind aSource
asProxyType :: a -> Proxy a -> aSource