{-# LANGUAGE ScopedTypeVariables, DataKinds, AllowAmbiguousTypes, PolyKinds #-} {-# LANGUAGE TypeApplications, TypeFamilies, FlexibleContexts #-} {-# LANGUAGE FlexibleInstances, RankNTypes #-} {-| Description : Encode versioned values Copyright : 2020 Sven Bartscher License : MPL-2.0 Maintainer : sven.bartscher@weltraumschlangen.de Stability : experimental Portability : GHC This module offers the monad 'VersionedPutM' (and the related 'VersionedPut' and 'VersionedPutter') and related operations to encode values in versioned containers -} module Data.Serialize.Versioned.Put ( VersionedPutM , VersionedPut , VersionedPutter , runVersionedPut , putUnversioned , putUnversionedResumable , putVersioned , embedVersionDomain ) where import Data.Serialize ( Put , PutM , putWord64be ) import Data.Serialize.Versioned.Put.Types import Data.Serialize.Versioned.Internal putVersion :: forall v. ValidVersion v => Put putVersion = putWord64be $ getVersionWord @v -- | Writes a versioned container by first writing an appropriate -- version tag, determined by looking that the type parameter @v@ and -- then writing the given operation as a body for the container. runVersionedPut :: forall d v a. (ValidVersion v) => VersionedPutM d v a -> PutM a runVersionedPut p = putVersion @v *> unVersionedPut p -- | A version of putUnversioned that allows you to resume encoding -- data with the outer version, without writing another version tag. putUnversionedResumable :: (ValidVersion v) => ((forall b. VersionedPutM d v b -> PutM b) -> PutM a) -> VersionedPutM d v a putUnversionedResumable f = VersionedPutM $ f unVersionedPut -- | Encodes a seperately versioned container into another versioned -- container. embedVersionDomain :: forall innerD innerV outerD outerV t. (ValidVersion innerV) => VersionedPutM innerD innerV t -> VersionedPutM outerD outerV t embedVersionDomain = putUnversioned . runVersionedPut