Skip to content

Commit ea61ca8

Browse files
committed
Update for simplified purescript-codec
1 parent 42bb14b commit ea61ca8

File tree

8 files changed

+122
-169
lines changed

8 files changed

+122
-169
lines changed

bower.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
],
1818
"dependencies": {
1919
"purescript-argonaut-core": "^7.0.0",
20-
"purescript-codec": "^5.0.0",
20+
"purescript-codec": "^6.0.0",
2121
"purescript-variant": "^8.0.0",
2222
"purescript-ordered-collections": "^3.0.0",
23-
"purescript-type-equality": "^4.0.0"
23+
"purescript-type-equality": "^4.0.1"
2424
},
2525
"devDependencies": {
26-
"purescript-argonaut-codecs": "^9.0.0",
27-
"purescript-quickcheck": "^8.0.0"
26+
"purescript-argonaut-codecs": "^9.1.0",
27+
"purescript-quickcheck": "^8.0.1"
2828
}
2929
}

src/Data/Codec/Argonaut.purs

Lines changed: 69 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -27,41 +27,38 @@ module Data.Codec.Argonaut
2727
, named
2828
, coercible
2929
, prismaticCodec
30-
, module Exports
30+
, module Codec
3131
) where
3232

3333
import Prelude
3434

35-
import Control.Monad.Reader (ReaderT(..), runReaderT)
36-
import Control.Monad.Writer (Writer, mapWriter, writer)
3735
import Data.Argonaut.Core as J
3836
import Data.Array as A
3937
import Data.Bifunctor (bimap, lmap)
4038
import Data.Bifunctor as BF
41-
import Data.Codec (BasicCodec, Codec, GCodec(..), basicCodec, bihoistGCodec, decode, encode)
42-
import Data.Codec (decode, encode, (<~<), (>~>), (~)) as Exports
39+
import Data.Codec (Codec(..), Codec')
40+
import Data.Codec (Codec(..), Codec', codec, codec', decode, encode, hoist, identity, (<~<), (>~>), (~)) as Codec
4341
import Data.Either (Either(..), note)
4442
import Data.Generic.Rep (class Generic)
4543
import Data.Int as I
4644
import Data.List ((:))
4745
import Data.List as L
48-
import Data.Maybe (Maybe(..), fromJust, maybe)
49-
import Data.Profunctor.Star (Star(..))
46+
import Data.Maybe (Maybe(..), maybe)
5047
import Data.String as S
5148
import Data.String.CodeUnits as SCU
5249
import Data.Symbol (class IsSymbol, reflectSymbol)
53-
import Data.Traversable (traverse)
50+
import Data.TraversableWithIndex (traverseWithIndex)
5451
import Data.Tuple (Tuple(..))
5552
import Foreign.Object as FO
56-
import Partial.Unsafe (unsafePartial)
5753
import Prim.Coerce (class Coercible)
5854
import Prim.Row as Row
55+
import Record.Unsafe as Record
5956
import Safe.Coerce (coerce)
6057
import Type.Proxy (Proxy)
6158
import Unsafe.Coerce (unsafeCoerce)
6259

6360
-- | Codec type for `Json` values.
64-
type JsonCodec a = BasicCodec (Either JsonDecodeError) J.Json a
61+
type JsonCodec a = Codec' (Either JsonDecodeError) J.Json a
6562

6663
-- | Error type for failures while decoding.
6764
data JsonDecodeError
@@ -100,7 +97,7 @@ printJsonDecodeError err =
10097

10198
-- | The "identity codec" for `Json` values.
10299
json JsonCodec J.Json
103-
json = basicCodec pure identity
100+
json = Codec.codec' pure identity
104101

105102
-- | A codec for `null` values in `Json`.
106103
null JsonCodec Unit
@@ -154,13 +151,10 @@ jobject = jsonPrimCodec "Object" J.toObject J.fromObject
154151
-- | codecIntArray = CA.array CA.int
155152
-- | ```
156153
array a. JsonCodec a JsonCodec (Array a)
157-
array codec = GCodec dec enc
158-
where
159-
dec = ReaderT \j →
160-
traverse (\(Tuple ix j') → BF.lmap (AtIndex ix) (decode codec j'))
161-
<<< A.mapWithIndex Tuple
162-
=<< decode jarray j
163-
enc = Star \xs → writer $ Tuple xs (J.fromArray (map (encode codec) xs))
154+
array codec =
155+
Codec.codec'
156+
(\j → traverseWithIndex (\ix j' → BF.lmap (AtIndex ix) (Codec.decode codec j')) =<< Codec.decode jarray j)
157+
(\a → J.fromArray (map (Codec.encode codec) a))
164158

165159
-- | Codec type for specifically indexed `JArray` elements.
166160
type JIndexedCodec a =
@@ -189,20 +183,17 @@ type JIndexedCodec a =
189183
-- | <*> _.age ~ CA.index 1 CA.int
190184
-- | ```
191185
indexedArray a. String JIndexedCodec a JsonCodec a
192-
indexedArray name =
193-
bihoistGCodec
194-
(\rReaderT (BF.lmap (Named name) <<< runReaderT r <=< decode jarray))
195-
(mapWriter (BF.rmap (J.fromArray <<< A.fromFoldable)))
186+
indexedArray name codec =
187+
Codec.codec'
188+
(\j → lmap (Named name) (Codec.decode codec =<< Codec.decode jarray j))
189+
(\a → Codec.encode jarray (A.fromFoldable (Codec.encode codec a)))
196190

197191
-- | A codec for an item in an `indexedArray`.
198192
index a. Int JsonCodec a JIndexedCodec a
199-
index ix codec = GCodec dec enc
200-
where
201-
dec = ReaderT \xs →
202-
BF.lmap (AtIndex ix) case A.index xs ix of
203-
Just val → decode codec val
204-
NothingLeft MissingValue
205-
enc = Star \val → writer $ Tuple val (pure (encode codec val))
193+
index ix codec =
194+
Codec.codec
195+
(\xs → BF.lmap (AtIndex ix) (maybe (Left MissingValue) (Codec.decode codec) (A.index xs ix)))
196+
(pure <<< Codec.encode codec)
206197

207198
-- | Codec type for `JObject` prop/value pairs.
208199
type JPropCodec a =
@@ -218,23 +209,17 @@ type JPropCodec a =
218209
-- | See also `Data.Codec.Argonaut.Record.object` for a more commonly useful
219210
-- | version of this function.
220211
object a. String JPropCodec a JsonCodec a
221-
object name =
222-
bihoistGCodec
223-
(\rReaderT (BF.lmap (Named name) <<< runReaderT r <=< decode jobject))
224-
(mapWriter (BF.rmap (J.fromObject <<< FO.fromFoldable)))
212+
object name codec =
213+
Codec.codec'
214+
(\j → lmap (Named name) (Codec.decode codec =<< Codec.decode jobject j))
215+
(\a → Codec.encode jobject (FO.fromFoldable (Codec.encode codec a)))
225216

226217
-- | A codec for a property of an object.
227218
prop a. String JsonCodec a JPropCodec a
228-
prop key codec = GCodec dec enc
229-
where
230-
dec ReaderT (FO.Object J.Json) (Either JsonDecodeError) a
231-
dec = ReaderT \obj →
232-
BF.lmap (AtKey key) case FO.lookup key obj of
233-
Just val → decode codec val
234-
NothingLeft MissingValue
235-
236-
enc Star (Writer (L.List (Tuple String J.Json))) a a
237-
enc = Star \val → writer $ Tuple val (pure (Tuple key (encode codec val)))
219+
prop key codec =
220+
Codec.codec
221+
(\obj → BF.lmap (AtKey key) (maybe (Left MissingValue) (Codec.decode codec) (FO.lookup key obj)))
222+
(pure <<< Tuple key <<< Codec.encode codec)
238223

239224
-- | The starting value for a object-record codec. Used with `recordProp` it
240225
-- | provides a convenient method for defining codecs for record types that
@@ -258,7 +243,7 @@ prop key codec = GCodec dec enc
258243
-- | See also `Data.Codec.Argonaut.Record.object` for a more commonly useful
259244
-- | version of this function.
260245
record JPropCodec {}
261-
record = GCodec (pure {}) (Star \val → writer (Tuple val L.Nil))
246+
record = Codec (const (pure {})) pure
262247

263248
-- | Used with `record` to define codecs for record types that encode into JSON
264249
-- | objects of the same shape. See the comment on `record` for an example.
@@ -271,31 +256,24 @@ recordProp
271256
JPropCodec (Record r)
272257
JPropCodec (Record r')
273258
recordProp p codecA codecR =
274-
let key = reflectSymbol p in GCodec (dec' key) (enc' key)
259+
let key = reflectSymbol p in Codec.codec (dec' key) (enc' key)
275260
where
276-
dec' String ReaderT (FO.Object J.Json) (Either JsonDecodeError) (Record r')
277-
dec' key = ReaderT \obj do
278-
r ← decode codecR obj
261+
dec' String FO.Object J.Json Either JsonDecodeError (Record r')
262+
dec' key obj = do
263+
r ← Codec.decode codecR obj
279264
a ← BF.lmap (AtKey key) case FO.lookup key obj of
280-
Just val → decode codecA val
265+
Just val → Codec.decode codecA val
281266
NothingLeft MissingValue
282-
pure $ unsafeSet key a r
267+
pure $ Record.unsafeSet key a r
283268

284-
enc' String Star (Writer (L.List (Tuple String J.Json))) (Record r') (Record r')
285-
enc' key = Star \val →
286-
writer $ Tuple val
287-
$ Tuple key (encode codecA (unsafeGet key val))
288-
: encode codecR (unsafeForget val)
269+
enc' String Record r' L.List (Tuple String J.Json)
270+
enc' key val =
271+
Tuple key (Codec.encode codecA (Record.unsafeGet key val))
272+
: Codec.encode codecR (unsafeForget val)
289273

290274
unsafeForget Record r' Record r
291275
unsafeForget = unsafeCoerce
292276

293-
unsafeSet String a Record r Record r'
294-
unsafeSet key a = unsafeCoerce <<< FO.insert key a <<< unsafeCoerce
295-
296-
unsafeGet String Record r' a
297-
unsafeGet s = unsafePartial fromJust <<< FO.lookup s <<< unsafeCoerce
298-
299277
-- | Used with `record` to define an optional field.
300278
-- |
301279
-- | This will only decode the property as `Nothing` if the field does not exist
@@ -311,41 +289,31 @@ recordPropOptional
311289
JsonCodec a
312290
JPropCodec (Record r)
313291
JPropCodec (Record r')
314-
recordPropOptional p codecA codecR =
315-
let key = reflectSymbol p in GCodec (dec' key) (enc' key)
292+
recordPropOptional p codecA codecR = Codec.codec dec' enc'
316293
where
317-
dec' String ReaderT (FO.Object J.Json) (Either JsonDecodeError) (Record r')
318-
dec' key = ReaderT \obj → do
319-
r ← decode codecR obj
294+
key String
295+
key = reflectSymbol p
296+
297+
dec' FO.Object J.Json Either JsonDecodeError (Record r')
298+
dec' obj = do
299+
r ← Codec.decode codecR obj
320300
a ← BF.lmap (AtKey key) case FO.lookup key obj of
321-
Just val → Just <$> decode codecA val
301+
Just val → Just <$> Codec.decode codecA val
322302
_ → Right Nothing
323-
pure $ unsafeSet key a r
303+
pure $ Record.unsafeSet key a r
324304

325-
enc' String Star (Writer (L.List (Tuple String J.Json))) (Record r') (Record r')
326-
enc' key = Star \val do
327-
let w = encode codecR (unsafeForget val)
328-
writer $ Tuple val case unsafeGet key val of
329-
Just a → Tuple key (encode codecA a) : w
305+
enc' Record r' L.List (Tuple String J.Json)
306+
enc' val = do
307+
let w = Codec.encode codecR (unsafeForget val)
308+
case Record.unsafeGet key val of
309+
Just a → Tuple key (Codec.encode codecA a) : w
330310
Nothing → w
331311

332312
unsafeForget Record r' Record r
333313
unsafeForget = unsafeCoerce
334314

335-
unsafeSet String Maybe a Record r Record r'
336-
unsafeSet key a = unsafeCoerce <<< FO.insert key a <<< unsafeCoerce
337-
338-
unsafeGet String Record r' Maybe a
339-
unsafeGet s = unsafePartial fromJust <<< FO.lookup s <<< unsafeCoerce
340-
341-
jsonPrimCodec
342-
a
343-
. String
344-
(J.Json Maybe a)
345-
(a J.Json)
346-
JsonCodec a
347-
jsonPrimCodec ty f =
348-
basicCodec (maybe (Left (TypeMismatch ty)) pure <<< f)
315+
jsonPrimCodec a. String (J.Json Maybe a) (a J.Json) JsonCodec a
316+
jsonPrimCodec ty f = Codec.codec' (maybe (Left (TypeMismatch ty)) pure <<< f)
349317

350318
-- | Helper function for defining recursive codecs in situations where the codec
351319
-- | definition causes a _"The value of <codec> is undefined here"_ error.
@@ -370,27 +338,27 @@ jsonPrimCodec ty f =
370338
-- | ```
371339
fix a. (JsonCodec a JsonCodec a) JsonCodec a
372340
fix f =
373-
basicCodec
374-
(\x → decode (f (fix f)) x)
375-
(\x → encode (f (fix f)) x)
341+
Codec.codec'
342+
(\x → Codec.decode (f (fix f)) x)
343+
(\x → Codec.encode (f (fix f)) x)
376344

377345
-- | A codec for introducing names into error messages - useful when definiting a codec for a type
378346
-- | synonym for a record, for instance.
379-
named a. String JsonCodec a -> JsonCodec a
347+
named a. String JsonCodec a JsonCodec a
380348
named name codec =
381-
basicCodec
382-
(lmap (Named name) <<< decode codec)
383-
(encode codec)
349+
Codec.codec'
350+
(lmap (Named name) <<< Codec.decode codec)
351+
(Codec.encode codec)
384352

385353
-- | A codec for types that can be safely coerced.
386354
-- |
387355
-- | Accepts the name of the target type as an argument to improve error messaging when the inner
388356
-- | codec fails.
389357
coercible a b. Coercible a b String JsonCodec a JsonCodec b
390358
coercible name codec =
391-
basicCodec
392-
(bimap (Named name) coerce <<< decode codec)
393-
(coerce (encode codec))
359+
Codec.codec'
360+
(bimap (Named name) coerce <<< Codec.decode codec)
361+
(coerce (Codec.encode codec))
394362

395363
-- | Adapts an existing codec with a pair of functions to allow a value to be
396364
-- | further refined. If the inner decoder fails an `UnexpectedValue` error will
@@ -432,7 +400,7 @@ coercible name codec =
432400
-- | Although for this latter case there are some other options too, in the form
433401
-- | of `Data.Codec.Argonaut.Generic.nullarySum` and `Data.Codec.Argonaut.Sum.enumSum`.
434402
prismaticCodec a b. String (a Maybe b) (b a) JsonCodec a JsonCodec b
435-
prismaticCodec name f g orig =
436-
basicCodec
437-
(\json' → note (Named name (UnexpectedValue json')) <<< f =<< decode orig json')
438-
(encode orig <<< g)
403+
prismaticCodec name f g codec =
404+
Codec.codec'
405+
(\j → note (Named name (UnexpectedValue j)) <<< f =<< Codec.decode codec j)
406+
(Codec.encode codec <<< g)

src/Data/Codec/Argonaut/Common.purs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ module Data.Codec.Argonaut.Common
1313
, module Data.Codec.Argonaut
1414
) where
1515

16-
import Prelude hiding (map, void)
16+
import Prelude hiding (map, void, identity)
1717

1818
import Data.Array as Array
1919
import Data.Array.NonEmpty as NEA
20-
import Data.Codec.Argonaut (JIndexedCodec, JPropCodec, JsonCodec, JsonDecodeError(..), array, boolean, char, codePoint, coercible, decode, encode, fix, index, indexedArray, int, jarray, jobject, json, named, null, number, object, printJsonDecodeError, prismaticCodec, prop, record, recordProp, recordPropOptional, string, void, (<~<), (>~>), (~))
20+
import Data.Codec.Argonaut (Codec(..), Codec', JIndexedCodec, JPropCodec, JsonCodec, JsonDecodeError(..), array, boolean, char, codePoint, codec, codec', coercible, decode, encode, fix, hoist, identity, index, indexedArray, int, jarray, jobject, json, named, null, number, object, printJsonDecodeError, prismaticCodec, prop, record, recordProp, recordPropOptional, string, void, (<~<), (>~>), (~))
2121
import Data.Codec.Argonaut.Sum (taggedSum)
2222
import Data.Either (Either(..))
2323
import Data.Functor as F

src/Data/Codec/Argonaut/Compat.purs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ module Data.Codec.Argonaut.Compat
44
, module Data.Codec.Argonaut.Common
55
) where
66

7-
import Prelude hiding (void)
7+
import Prelude hiding (identity, map, void)
88

99
import Data.Argonaut.Core as J
1010
import Data.Bifunctor as BF
11-
import Data.Codec (basicCodec, mapCodec)
12-
import Data.Codec.Argonaut.Common (JIndexedCodec, JPropCodec, JsonCodec, JsonDecodeError(..), array, boolean, char, codePoint, coercible, decode, either, encode, fix, index, indexedArray, int, jarray, jobject, json, list, named, nonEmptyArray, nonEmptyList, nonEmptySet, nonEmptyString, null, number, object, printJsonDecodeError, prismaticCodec, prop, record, recordProp, recordPropOptional, set, string, tuple, void, (<~<), (>~>), (~))
11+
import Data.Codec as Codec
12+
import Data.Codec.Argonaut.Common (Codec(..), Codec', JIndexedCodec, JPropCodec, JsonCodec, JsonDecodeError(..), array, boolean, char, codePoint, codec, codec', coercible, decode, either, encode, fix, hoist, identity, index, indexedArray, int, jarray, jobject, json, list, map, named, nonEmptyArray, nonEmptyList, nonEmptySet, nonEmptyString, null, number, object, printJsonDecodeError, prismaticCodec, prop, record, recordProp, recordPropOptional, set, string, tuple, void, (<~<), (>~>), (~))
1313
import Data.Either (Either)
14-
import Data.Functor as F
14+
import Data.Functor as Functor
1515
import Data.Maybe (Maybe(..))
1616
import Data.Traversable (traverse)
1717
import Data.Tuple (Tuple(..))
@@ -24,7 +24,7 @@ import Foreign.Object as FO
2424
-- | Note: this codec cannot represent nested `Maybe` values in a lossless
2525
-- | manner.
2626
maybe a. JsonCodec a JsonCodec (Maybe a)
27-
maybe codec = basicCodec dec enc
27+
maybe codec = Codec.codec' dec enc
2828
where
2929
dec J.Json Either JsonDecodeError (Maybe a)
3030
dec j
@@ -45,14 +45,12 @@ maybe codec = basicCodec dec enc
4545
-- | ```
4646
foreignObject a. JsonCodec a JsonCodec (FO.Object a)
4747
foreignObject codec =
48-
mapCodec
49-
(BF.lmap (Named "StrMap") <<< F.map fromArray <<< traverse decodeItem <<< FO.toUnfoldable)
50-
(F.map (encode codec))
51-
jobject
48+
Codec.codec'
49+
(BF.lmap (Named "StrMap") <<< Functor.map fromArray <<< traverse decodeItem <<< FO.toUnfoldable <=< decode jobject)
50+
(encode jobject <<< Functor.map (encode codec))
5251
where
5352
fromArray v. Array (Tuple String v) FO.Object v
5453
fromArray = FO.fromFoldable
5554

5655
decodeItem Tuple String J.Json Either JsonDecodeError (Tuple String a)
57-
decodeItem (Tuple key value) =
58-
BF.bimap (AtKey key) (Tuple key) (decode codec value)
56+
decodeItem (Tuple key value) = BF.bimap (AtKey key) (Tuple key) (decode codec value)

src/Data/Codec/Argonaut/Generic.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Type.Proxy (Proxy(..))
2424
-- |```
2525
nullarySum a r. Generic a r NullarySumCodec r String CA.JsonCodec a
2626
nullarySum name =
27-
C.basicCodec
27+
C.codec'
2828
(map to <<< nullarySumDecode name)
2929
(nullarySumEncode <<< from)
3030

0 commit comments

Comments
 (0)