| CARVIEW |
codec: Simple bidirectional serialization
Downloads
- codec-0.2.1.tar.gz [browse] (Cabal source package)
- Package description (as included in the package)
Maintainer's Corner
For package maintainers and hackage trustees
Candidates
| Versions [RSS] | 0.1, 0.1.1, 0.2, 0.2.1 |
|---|---|
| Dependencies | aeson (>=1.0.0.0), base (>=4.6 && <6), binary, binary-bits, bytestring, mtl, profunctors, template-haskell, text, transformers, unordered-containers, vector [details] |
| License | BSD-3-Clause |
| Author | Patrick Chilton |
| Maintainer | chpatrick@gmail.com |
| Uploaded | by PatrickChilton at 2017-04-21T18:46:02Z |
| Category | Data |
| Home page | https://github.com/chpatrick/codec |
| Source repo | head: git clone https://github.com/chpatrick/codec.git |
| Distributions | |
| Reverse Dependencies | 1 direct, 0 indirect [details] |
| Downloads | 3908 total (16 in the last 30 days) |
| Rating | 2.0 (votes: 1) [estimated by Bayesian average] |
| Your Rating |
|
| Status | Docs available [build log] Last success reported on 2017-04-21 [all 1 reports] |
Readme for codec-0.2.1
[back to package description]Codec

Codec makes it simple to write composable bidirectional serializers with a consistent interface.
Just define your data type normally:
data RecordB = RecordB
{ recordBString :: String
, recordBDouble :: Double
} deriving (Eq, Ord, Show)
and then associate each field with a codec using the =. operator:
recordBObjCodec :: JSONCodec RecordB
recordBObjCodec = asObject "RecordB" $
RecordB
<$> recordBString =. field "string"
<*> recordBDouble =. field "double"
That's it! If you want, you can now define ToJSON and FromJSON instances, or just use it directly:
instance ToJSON RecordB where
toJSON = toJSONCodec recordBObjCodec
toEncoding = toEncodingCodec recordBObjCodec
instance FromJSON RecordB where
parseJSON = parseJSONCodec recordBObjCodec
Support can be added for almost any serialization library, but aeson and binary support is included.
JSON example:
data RecordA = RecordA
{ recordAInt :: Int
, recordANestedObj :: RecordB
, recordANestedArr :: RecordB
, recordANestedObjs :: [ RecordB ]
} deriving (Eq, Ord, Show)
data RecordB = RecordB
{ recordBString :: String
, recordBDouble :: Double
} deriving (Eq, Ord, Show)
recordACodec :: JSONCodec RecordA
recordACodec = asObject "RecordA" $
RecordA
<$> recordAInt =. field "int"
<*> recordANestedObj =. field' "nestedObj" recordBObjCodec
<*> recordANestedArr =. field' "nestedArr" recordBArrCodec
<*> recordANestedObjs =. field' "nestedObjs" (arrayOf' id id recordBObjCodec)
recordBObjCodec :: JSONCodec RecordB
recordBObjCodec = asObject "RecordB" $
RecordB
<$> recordBString =. field "string"
<*> recordBDouble =. field "double"
-- serialize to array elements
recordBArrCodec :: JSONCodec RecordB
recordBArrCodec = asArray "RecordB" $
RecordB
<$> recordBString =. element
<*> recordBDouble =. element
Binary example:
data RecordA = RecordA
{ recordAInt64 :: Int64
, recordAWord8 :: Word8
, recordANestedB :: RecordB
} deriving (Eq, Ord, Show)
data RecordB = RecordB
{ recordBWord16 :: Word16
, recordBByteString64 :: BS.ByteString
} deriving (Eq, Ord, Show)
recordACodec :: BinaryCodec RecordA
recordACodec =
RecordA
<$> recordAInt64 =. int64le
<*> recordAWord8 =. word8
<*> recordANestedB =. recordBCodec
recordBCodec :: BinaryCodec RecordB
recordBCodec =
RecordB
<$> recordBWord16 =. word16host
<*> recordBByteString64 =. byteString 64
A Codec is just a combination of a deserializer r a, and a serializer c -> w a.
data CodecFor r w c a = Codec
{ codecIn :: r a
, codecOut :: c -> w a
}
type Codec r w a = CodecFor r w a a
With binary for example, r is Get and w is PutM. The reason we have an extra parameter c is so that we can associate a Codec with a particular field using the =. operator:
(=.) :: (c' -> c) -> CodecFor r w c a -> CodecFor r w c' a
Codec is an instance of Functor, Applicative, Monad and Profunctor. You can serialize in any order you like, regardless of field order in the data type:
recordBCodecFlipped :: BinaryCodec RecordB
recordBCodecFlipped = do
bs64 <- recordBByteString64 =. byteString 64
RecordB
<$> recordBWord16 =. word16host
<*> pure bs64
Contributors
=. operator and Profunctor approach thanks to Xia Li-yao