Skip to content

Commit 8da7fa4

Browse files
authored
Merge pull request #12 from kRITZCREEK/documentation
Documentation for prismaticCodec
2 parents b17465f + 3a3e528 commit 8da7fa4

File tree

8 files changed

+130
-3
lines changed

8 files changed

+130
-3
lines changed

src/Data/Codec/Argonaut.purs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module Data.Codec.Argonaut
1111
, char
1212
, jarray
1313
, jobject
14+
, void
1415
, array
1516
, JIndexedCodec
1617
, indexedArray
@@ -125,6 +126,11 @@ jobject ∷ JsonCodec J.JObject
125126
jobject = jsonPrimCodec "Object" J.toObject J.fromObject
126127

127128
-- | A codec for `Array` values.
129+
-- |```purescript
130+
-- | decodeIntArray ∷ Json → Either JsonDecodeError (Array Int)
131+
-- | decodeIntArray = decode (array int)
132+
-- |```
133+
128134
array a. JsonCodec a JsonCodec (Array a)
129135
array codec = GCodec dec enc
130136
where
@@ -143,6 +149,18 @@ type JIndexedCodec a =
143149
a a
144150

145151
-- | A codec for types that are encoded as an array with a specific layout.
152+
-- |
153+
-- | For example, given that we'd like to encode a Person as a 2-element array,
154+
-- | like so `[ "Karl", 25 ]`, we could write the following codec:
155+
-- |
156+
-- | ```purescript
157+
-- | type Person = { name ∷ String, age ∷ Int }
158+
-- |
159+
-- | JA.indexedArray "Test Object" $
160+
-- | { name: _, age: _ }
161+
-- | <$> _.name ~ index 0 JA.string
162+
-- | <*> _.age ~ index 1 JA.int
163+
-- | ```
146164
indexedArray a. String JIndexedCodec a JsonCodec a
147165
indexedArray name =
148166
bihoistGCodec
@@ -254,8 +272,32 @@ fix f =
254272
-- |
255273
-- | This function is named as such as the pair of functions it accepts
256274
-- | correspond with the `preview` and `view` functions of a `Prism`-style lens.
275+
-- |
276+
-- | For example, in order to parse a mapping from an enum to strings, which
277+
-- | doesn't match up nicely with `Data.Codec.Argonaut.Sum.enumSum` we can use
278+
-- | prismaticCodec:
279+
-- |
280+
-- | ```purescript
281+
-- | data Direction = North | South | West | East
282+
-- |
283+
-- | directionCodec :: JsonCodec Direction
284+
-- | directionCodec = prismaticCodec dec enc string
285+
-- | where
286+
-- | dec = case _ of
287+
-- | "N" -> Just North
288+
-- | "S" -> Just South
289+
-- | "W" -> Just West
290+
-- | "E" -> Just East
291+
-- | _ -> Nothing
292+
-- |
293+
-- | enc = case _ of
294+
-- | North -> "N"
295+
-- | South -> "S"
296+
-- | West -> "W"
297+
-- | East -> "E"
298+
-- | ```
257299
prismaticCodec a b. (a Maybe b) (b a) JsonCodec a JsonCodec b
258300
prismaticCodec f g orig =
259301
basicCodec
260-
(\json → note (UnexpectedValue json) <<< f =<< (decode orig json))
302+
(\json' → note (UnexpectedValue json') <<< f =<< decode orig json')
261303
(encode orig <<< g)

src/Data/Codec/Argonaut/Common.purs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import Data.StrMap as SM
1818
import Data.Tuple (Tuple(..), fst, snd)
1919

2020
-- | A codec for `Maybe` values.
21+
-- |
22+
-- | NOTE: This is not suitable to en/decode null values. If you need these kinds of codecs,
23+
-- | look into `Data.Codec.Argonaut.Compat`
2124
maybe a. JsonCodec a JsonCodec (Maybe a)
2225
maybe codec = taggedSum "Maybe" printTag parseTag dec enc
2326
where

src/Data/Codec/Argonaut/Compat.purs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import Data.Tuple (Tuple(..))
2121

2222
-- | A codec for `Maybe` values.
2323
-- |
24+
-- | Encodes and decodes `Nothing` as `null`
25+
-- |
2426
-- | Note: this codec cannot represent nested `Maybe` values in a lossless
2527
-- | manner.
2628
maybe a. JsonCodec a JsonCodec (Maybe a)
@@ -38,6 +40,10 @@ maybe codec = basicCodec dec enc
3840
-- | A codec for `StrMap` values.
3941
-- |
4042
-- | Encodes as a JSON object with the keys as properties.
43+
-- |
44+
-- | ```purescript
45+
-- | encode (strMap int) (Data.StrMap.fromFoldable [Tuple "a" 1, Tuple "b" 2]) == "{ \"a\": 1, \"b\": 2}"
46+
-- | ```
4147
strMap a. JsonCodec a JsonCodec (SM.StrMap a)
4248
strMap codec =
4349
mapCodec

src/Data/Codec/Argonaut/Generic.purs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ import Data.Either (Either(..), note)
1010
import Data.Generic.Rep (class Generic, Constructor(..), NoArguments(..), Sum(..), from, to)
1111
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
1212

13+
-- | Encodes nullary sums with a Generic instance as strings that match the constructor names.
14+
-- |
15+
-- | ```purescript
16+
-- | import Data.Argonaut as J
17+
-- |
18+
-- | data MySum = Ctor1 | Ctor2 | MoarCtors
19+
-- | derive instance genericMySum ∷ Generic MySum _
20+
-- |
21+
-- | encode nullarySum Ctor1 == J.fromString "Ctor1"
22+
-- | decode nullarySum (J.fromString "MoarCtors") == Right MoarCtors
23+
-- |```
1324
nullarySum a r. Generic a r NullarySumCodec r String CA.JsonCodec a
1425
nullarySum name =
1526
C.basicCodec

src/Data/Codec/Argonaut/Record.purs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ instance rowListCodecCons ∷
3434
tail = rowListCodec (R.RLProxy R.RLProxy rs) ((unsafeCoerce Record ri Record ri') codecs)
3535

3636
-- | Constructs a record codec from a record of codecs.
37+
-- |
38+
-- | ```purescript
39+
-- | type Person = { name ∷ String, age ∷ Int }
40+
-- |
41+
-- | personCodec ∷ CA.JsonCodec Person
42+
-- | personCodec = CA.object "Person" (record { name: CA.string, age: CA.int })
43+
-- |
44+
-- | decode personCodec "{ name: \"Carl\", age:\"25\" }" == Right { name: "Carl", age: 25 }
45+
-- | ```
46+
3747
record
3848
ri ro rl
3949
. R.RowToList ri rl

src/Data/Codec/Argonaut/Variant.purs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,28 @@ import Type.Equality as TE
2020
import Type.Row as R
2121
import Unsafe.Coerce (unsafeCoerce)
2222

23+
-- | Allows building codecs for variants in combination with variantCase.
24+
-- |
25+
-- | Commonly used to write decoders for sum-types, by providing a mapping from
26+
-- | and to a Variant from that type and then using `dimap`.
27+
-- |
28+
-- |```purescript
29+
-- | codecMaybe ∷ ∀ a. JA.JsonCodec a → JA.JsonCodec (Maybe a)
30+
-- | codecMaybe codecA =
31+
-- | dimap toVariant fromVariant
32+
-- | (JAV.variant
33+
-- | # JAV.variantCase _Just (Right codecA)
34+
-- | # JAV.variantCase _Nothing (Left unit))
35+
-- | where
36+
-- | toVariant = case _ of
37+
-- | Just a → V.inj _Just a
38+
-- | Nothing → V.inj _Nothing unit
39+
-- | fromVariant = V.case_
40+
-- | # V.on _Just Just
41+
-- | # V.on _Nothing (const Nothing)
42+
-- | _Just = SProxy ∷ SProxy "just"
43+
-- | _Nothing = SProxy ∷ SProxy "nothing"
44+
-- |```
2345
variant JsonCodec (Variant ())
2446
variant = GCodec (ReaderT (Left <<< UnexpectedValue)) (Star case_)
2547

test/Test/Generic.purs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module Test.Generic where
2+
3+
import Prelude
4+
5+
import Control.Monad.Eff.Console (log)
6+
import Data.Codec.Argonaut.Generic (nullarySum)
7+
import Data.Generic.Rep (class Generic)
8+
import Data.Generic.Rep.Show (genericShow)
9+
import Test.QuickCheck (QC, quickCheck)
10+
import Test.QuickCheck.Arbitrary (genericArbitrary)
11+
import Test.QuickCheck.Gen (Gen)
12+
import Test.Util (propCodec)
13+
14+
data MySum = Ctor1 | Ctor2 | MoarCtors
15+
16+
derive instance eqMySumEq MySum
17+
derive instance genericMySumGeneric MySum _
18+
19+
instance showMySumShow MySum where
20+
show = genericShow
21+
22+
genMySum Gen MySum
23+
genMySum = genericArbitrary
24+
25+
main QC () Unit
26+
main = do
27+
log "Check nullarySum"
28+
quickCheck (propCodec genMySum (nullarySum "MySum"))

test/Test/Main.purs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import Control.Monad.Eff.Console (log)
66
import Test.Common as Common
77
import Test.Compat as Compat
88
import Test.Migration as Migration
9-
import Test.Prim as Prim
9+
import Test.Prim as TestPrim
10+
import Test.Generic as Generic
1011
import Test.QuickCheck (QC)
1112
import Test.Variant as Variant
1213
import Test.Record as Record
@@ -15,7 +16,7 @@ main :: QC () Unit
1516
main = do
1617
log "Checking Prim codecs"
1718
log "------------------------------------------------------------"
18-
Prim.main
19+
TestPrim.main
1920
log ""
2021
log "Checking Common codecs"
2122
log "------------------------------------------------------------"
@@ -36,3 +37,7 @@ main = do
3637
log "Checking Migration codecs"
3738
log "------------------------------------------------------------"
3839
Migration.main
40+
log ""
41+
log "Checking Generic codecs"
42+
log "------------------------------------------------------------"
43+
Generic.main

0 commit comments

Comments
 (0)