Skip to content

Commit 90d5485

Browse files
committed
Add README.
1 parent 62b0d8d commit 90d5485

2 files changed

Lines changed: 123 additions & 45 deletions

File tree

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Data.Codec
2+
3+
Tired of writing complementary `parseJSON`/`toJSON`, `peek`/`poke` or Binary `get`/`put` functions?
4+
5+
`codec` provides easy bidirectional serialization of plain Haskell records in any Applicative context.
6+
All you need to do is provide a de/serializer for every record field in any order you like,
7+
and you get a de/serializer for the whole structure. The type system ensures that you provide
8+
every record exactly once. It also includes a library for general record construction in an Applicative context,
9+
of which creating codecs is just one application.
10+
11+
JSON!
12+
13+
userCodec :: JSONCodec User
14+
userCodec = obj "user object" $
15+
User
16+
$>> f_username >-< "user"
17+
>>> f_userEmail >-< "email"
18+
>>> f_userLanguages >-< "languages"
19+
>>> f_userReferrer >-< opt "referrer"
20+
21+
instance FromJSON User where
22+
parseJSON = parseVal userCodec
23+
24+
instance ToJSON User where
25+
toJSON = produceVal userCodec
26+
27+
Bit fields!
28+
29+
ipv4Codec :: BinaryCodec IPv4
30+
ipv4Codec = toBytes $
31+
IPv4
32+
$>> f_version >-< word8 4
33+
>>> f_ihl >-< word8 4
34+
>>> f_dscp >-< word8 6
35+
>>> f_ecn >-< word8 2
36+
>>> f_totalLength >-< word16be 16
37+
>>> f_identification >-< word16be 16
38+
>>> f_flags >-< word8 3
39+
>>> f_fragmentOffset >-< word16be 13
40+
>>> f_timeToLive >-< word8 8
41+
>>> f_protocol >-< word8 8
42+
>>> f_headerChecksum >-< word16be 16
43+
>>> f_sourceIP >-< word32be 32
44+
>>> f_destIP >-< word32be 32
45+
46+
instance Binary IPv4 where
47+
get = parse ipv4Codec
48+
put = produce ipv4Codec
49+
50+
Storable!
51+
52+
timeSpecCodec :: ForeignCodec TimeSpec
53+
timeSpecCodec =
54+
TimeSpec
55+
$>> f_seconds >-< field (#offset struct timespec, tv_sec) cInt
56+
>>> f_nanoseconds >-< field (#offset struct timespec, tv_nsec) cInt
57+
58+
instance Storable TimeSpec where
59+
peek = peekWith timeSpecCodec
60+
poke = pokeWith timeSpecCodec
61+
...
62+
63+
All of these examples use the same types and logic for constructing Codecs,
64+
and it's very easy to create Codecs for any parsing/serialization library.

codec.cabal

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,62 +3,76 @@ version: 0.1
33
license: BSD3
44
synopsis: First-class record construction and bidirectional serialization
55
description:
6-
Easy bidirectional serialization of plain Haskell types in any Applicative context.
7-
Serialization can occur in any field order and the type system
8-
ensures that every field is provided once.
6+
= Data.Codec
7+
#data.codec#
98
.
10-
JSON!
9+
Tired of writing complementary @parseJSON@\/@toJSON@, @peek@\/@poke@ or
10+
Binary @get@\/@put@ functions?
1111
.
12-
@
13-
userCodec :: JSONCodec User
14-
userCodec = obj "user object" $
15-
&#x20; User
16-
&#x20; $>> f_username >-< "user"
17-
&#x20; >>> f_userEmail >-< "email"
18-
&#x20; >>> f_userLanguages >-< "languages"
19-
&#x20; >>> f_userReferrer >-< opt "referrer"
12+
@codec@ provides easy bidirectional serialization of plain Haskell
13+
records in any Applicative context. All you need to do is provide a
14+
de\/serializer for every record field in any order you like, and you get
15+
a de\/serializer for the whole structure. The type system ensures that
16+
you provide every record exactly once. It also includes a library for
17+
general record construction in an Applicative context, of which creating
18+
codecs is just one application.
2019
.
21-
instance FromJSON User where
22-
&#x20; parseJSON = parseVal userCodec
20+
JSON!
2321
.
24-
instance ToJSON User where
25-
&#x20; toJSON = produceVal userCodec
26-
@
22+
> userCodec :: JSONCodec User
23+
> userCodec = obj "user object" $
24+
> User
25+
> $>> f_username >-< "user"
26+
> >>> f_userEmail >-< "email"
27+
> >>> f_userLanguages >-< "languages"
28+
> >>> f_userReferrer >-< opt "referrer"
29+
>
30+
> instance FromJSON User where
31+
> parseJSON = parseVal userCodec
32+
>
33+
> instance ToJSON User where
34+
> toJSON = produceVal userCodec
2735
.
2836
Bit fields!
2937
.
30-
@
31-
ipv4Codec :: BitCodec IPv4
32-
ipv4Codec =
33-
&#x20; IPv4
34-
&#x20; $>> f_version >-< word8 4
35-
&#x20; >>> f_ihl >-< word8 4
36-
&#x20; >>> f_dscp >-< word8 6
37-
&#x20; >>> f_ecn >-< word8 2
38-
&#x20; >>> f_totalLength >-< word16be 16
39-
&#x20; >>> f_identification >-< word16be 16
40-
&#x20; >>> f_flags >-< word8 3
41-
&#x20; >>> f_fragmentOffset >-< word16be 13
42-
&#x20; >>> f_timeToLive >-< word8 8
43-
&#x20; >>> f_protocol >-< word8 8
44-
&#x20; >>> f_headerChecksum >-< word16be 16
45-
&#x20; >>> f_sourceIP >-< word32be 32
46-
&#x20; >>> f_destIP >-< word32be 32
47-
@
38+
> ipv4Codec :: BinaryCodec IPv4
39+
> ipv4Codec = toBytes $
40+
> IPv4
41+
> $>> f_version >-< word8 4
42+
> >>> f_ihl >-< word8 4
43+
> >>> f_dscp >-< word8 6
44+
> >>> f_ecn >-< word8 2
45+
> >>> f_totalLength >-< word16be 16
46+
> >>> f_identification >-< word16be 16
47+
> >>> f_flags >-< word8 3
48+
> >>> f_fragmentOffset >-< word16be 13
49+
> >>> f_timeToLive >-< word8 8
50+
> >>> f_protocol >-< word8 8
51+
> >>> f_headerChecksum >-< word16be 16
52+
> >>> f_sourceIP >-< word32be 32
53+
> >>> f_destIP >-< word32be 32
54+
>
55+
> instance Binary IPv4 where
56+
> get = parse ipv4Codec
57+
> put = produce ipv4Codec
4858
.
4959
Storable!
5060
.
51-
@
52-
timeSpecCodec :: ForeignCodec TimeSpec
53-
timeSpecCodec =
54-
&#x20; TimeSpec
55-
&#x20; $>> f_seconds >-< field (#offset struct timespec, tv_sec) cInt
56-
&#x20; >>> f_nanoseconds >-< field (#offset struct timespec, tv_nsec) cInt
61+
> timeSpecCodec :: ForeignCodec TimeSpec
62+
> timeSpecCodec =
63+
> TimeSpec
64+
> $>> f_seconds >-< field (#offset struct timespec, tv_sec) cInt
65+
> >>> f_nanoseconds >-< field (#offset struct timespec, tv_nsec) cInt
66+
>
67+
> instance Storable TimeSpec where
68+
> peek = peekWith timeSpecCodec
69+
> poke = pokeWith timeSpecCodec
70+
> ...
71+
.
72+
All of these examples use the same types and logic for constructing
73+
Codecs, and it\'s very easy to create Codecs for any
74+
parsing\/serialization library.
5775
.
58-
instance Storable TimeSpec where
59-
&#x20; peek = peekWith timeSpecCodec
60-
&#x20; poke = pokeWith timeSpecCodec
61-
@
6276
See "Data.Codec" for an introduction.
6377
author: Patrick Chilton
6478
maintainer: chpatrick@gmail.com

0 commit comments

Comments
 (0)