@@ -18,8 +18,7 @@ module Data.Codec.Argonaut.Sum
18
18
, sumFlatWith
19
19
, sumWith
20
20
, taggedSum
21
- )
22
- where
21
+ ) where
23
22
24
23
import Prelude
25
24
@@ -110,12 +109,15 @@ taggedSum name printTag parseTag f g = Codec.codec decodeCase encodeCase
110
109
111
110
data Encoding
112
111
= EncodeNested
113
- { unwrapSingleArguments ∷ Boolean }
112
+ { unwrapSingleArguments ∷ Boolean
113
+ , mapTag ∷ String → String
114
+ }
114
115
| EncodeTagged
115
116
{ tagKey ∷ String
116
117
, valuesKey ∷ String
117
118
, omitEmptyArguments ∷ Boolean
118
119
, unwrapSingleArguments ∷ Boolean
120
+ , mapTag ∷ String → String
119
121
}
120
122
121
123
defaultEncoding ∷ Encoding
@@ -124,6 +126,7 @@ defaultEncoding = EncodeTagged
124
126
, valuesKey: " values"
125
127
, unwrapSingleArguments: false
126
128
, omitEmptyArguments: false
129
+ , mapTag: identity
127
130
}
128
131
129
132
-- ------------------------------------------------------------------------------
@@ -301,9 +304,10 @@ checkTag tagKey obj expectedTag = do
301
304
$ TypeMismatch (" Expecting tag `" <> expectedTag <> " `, got `" <> tag <> " `" )
302
305
303
306
parseNoFields ∷ Encoding → Json → String → Either JsonDecodeError Unit
304
- parseNoFields encoding json expectedTag =
307
+ parseNoFields encoding json expectedTagRaw =
305
308
case encoding of
306
- EncodeNested {} → do
309
+ EncodeNested { mapTag } → do
310
+ let expectedTag = mapTag expectedTagRaw ∷ String
307
311
obj ← CA .decode jobject json
308
312
val ←
309
313
( Obj .lookup expectedTag obj # note (TypeMismatch (" Expecting a property `" <> expectedTag <> " `" ))
@@ -313,7 +317,8 @@ parseNoFields encoding json expectedTag =
313
317
$ Left
314
318
$ TypeMismatch " Expecting an empty array"
315
319
316
- EncodeTagged { tagKey, valuesKey, omitEmptyArguments } → do
320
+ EncodeTagged { tagKey, valuesKey, omitEmptyArguments, mapTag } → do
321
+ let expectedTag = mapTag expectedTagRaw ∷ String
317
322
obj ← CA .decode jobject json
318
323
checkTag tagKey obj expectedTag
319
324
when (not omitEmptyArguments) do
@@ -327,8 +332,9 @@ parseNoFields encoding json expectedTag =
327
332
$ TypeMismatch " Expecting an empty array"
328
333
329
334
parseSingleField ∷ Encoding → Json → String → Either JsonDecodeError Json
330
- parseSingleField encoding json expectedTag = case encoding of
331
- EncodeNested { unwrapSingleArguments } → do
335
+ parseSingleField encoding json expectedTagRaw = case encoding of
336
+ EncodeNested { unwrapSingleArguments, mapTag } → do
337
+ let expectedTag = mapTag expectedTagRaw ∷ String
332
338
obj ← CA .decode jobject json
333
339
val ←
334
340
( Obj .lookup expectedTag obj # note (TypeMismatch (" Expecting a property `" <> expectedTag <> " `" ))
@@ -341,7 +347,8 @@ parseSingleField encoding json expectedTag = case encoding of
341
347
[ head ] → pure head
342
348
_ → Left $ TypeMismatch " Expecting exactly one element"
343
349
344
- EncodeTagged { tagKey, valuesKey, unwrapSingleArguments } → do
350
+ EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, mapTag } → do
351
+ let expectedTag = mapTag expectedTagRaw ∷ String
345
352
obj ← CA .decode jobject json
346
353
checkTag tagKey obj expectedTag
347
354
val ←
@@ -357,16 +364,18 @@ parseSingleField encoding json expectedTag = case encoding of
357
364
_ → Left $ TypeMismatch " Expecting exactly one element"
358
365
359
366
parseManyFields ∷ Encoding → Json → String → Either JsonDecodeError (Array Json )
360
- parseManyFields encoding json expectedTag =
367
+ parseManyFields encoding json expectedTagRaw =
361
368
case encoding of
362
- EncodeNested {} → do
369
+ EncodeNested { mapTag } → do
370
+ let expectedTag = mapTag expectedTagRaw ∷ String
363
371
obj ← CA .decode jobject json
364
372
val ←
365
373
( Obj .lookup expectedTag obj # note (TypeMismatch (" Expecting a property `" <> expectedTag <> " `" ))
366
374
) ∷ _ Json
367
375
CA .decode CA .jarray val
368
376
369
- EncodeTagged { tagKey, valuesKey } → do
377
+ EncodeTagged { tagKey, valuesKey, mapTag } → do
378
+ let expectedTag = mapTag expectedTagRaw ∷ String
370
379
obj ← CA .decode jobject json
371
380
checkTag tagKey obj expectedTag
372
381
val ←
@@ -376,10 +385,11 @@ parseManyFields encoding json expectedTag =
376
385
CA .decode CA .jarray val
377
386
378
387
encodeSumCase ∷ Encoding → String → Array Json → Json
379
- encodeSumCase encoding tag jsons =
388
+ encodeSumCase encoding rawTag jsons =
380
389
case encoding of
381
- EncodeNested { unwrapSingleArguments } →
390
+ EncodeNested { unwrapSingleArguments, mapTag } →
382
391
let
392
+ tag = mapTag rawTag ∷ String
383
393
val = case jsons of
384
394
[] → CA .encode CA .jarray []
385
395
[ json ] | unwrapSingleArguments → json
@@ -389,8 +399,9 @@ encodeSumCase encoding tag jsons =
389
399
[ tag /\ val
390
400
]
391
401
392
- EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, omitEmptyArguments } →
402
+ EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, omitEmptyArguments, mapTag } →
393
403
let
404
+ tag = mapTag rawTag ∷ String
394
405
tagEntry =
395
406
Just (tagKey /\ CA .encode CA .string tag) ∷ Maybe (String /\ Json )
396
407
valEntry =
@@ -412,7 +423,7 @@ defaultFlatEncoding = { tag: Proxy }
412
423
sumFlat ∷ ∀ r rep a . GFlatCases " tag" r rep ⇒ Generic a rep ⇒ String → Record r → JsonCodec a
413
424
sumFlat = sumFlatWith defaultFlatEncoding
414
425
415
- sumFlatWith ∷ ∀ @tag r rep a . GFlatCases tag r rep ⇒ Generic a rep ⇒ FlatEncoding tag -> String → Record r → JsonCodec a
426
+ sumFlatWith ∷ ∀ @tag r rep a . GFlatCases tag r rep ⇒ Generic a rep ⇒ FlatEncoding tag → String → Record r → JsonCodec a
416
427
sumFlatWith _ name r =
417
428
dimap from to $ codec' dec enc
418
429
where
@@ -529,6 +540,39 @@ instance gFlatCasesSum ∷
529
540
rhs = gFlatCasesDecode @tag r2 tagged ∷ _ rhs
530
541
(Inl <$> lhs) <|> (Inr <$> rhs)
531
542
543
+ -- ------------------------------------------------------------------------------
544
+
545
+ sumEnum ∷ ∀ r rep a . GEnumCases r rep ⇒ Generic a rep ⇒ String → Record r → JsonCodec a
546
+ sumEnum = unsafeCoerce 1
547
+
548
+ class GEnumCases ∷ Row Type → Type → Constraint
549
+ class
550
+ GEnumCases r rep
551
+ where
552
+ gEnumCasesEncode ∷ Record r → rep → Json
553
+ gEnumCasesDecode ∷ Record r → Json → Either JsonDecodeError rep
554
+
555
+ instance gEnumCasesConstructorNoArg ∷
556
+ ( Row.Cons name Unit () rc
557
+ , IsSymbol name
558
+ ) ⇒
559
+ GEnumCases rc (Constructor name NoArguments ) where
560
+ gEnumCasesEncode ∷ Record rc → Constructor name NoArguments → Json
561
+ gEnumCasesEncode _ _ =
562
+ let
563
+ name = reflectSymbol (Proxy @name) ∷ String
564
+ in
565
+ encodeSumCase defaultEncoding name []
566
+
567
+ gEnumCasesDecode ∷ Record rc → Json → Either JsonDecodeError (Constructor name NoArguments )
568
+ gEnumCasesDecode _ json = do
569
+ let name = reflectSymbol (Proxy @name) ∷ String
570
+
571
+ parseNoFields defaultEncoding json name
572
+ pure $ Constructor NoArguments
573
+
574
+ -- ------------------------------------------------------------------------------
575
+
532
576
-- | Same as `Record.delete` but deleting only happens at the type level
533
577
-- | and the value is left untouched.
534
578
unsafeDelete ∷ ∀ r1 r2 l a . IsSymbol l ⇒ Row.Lacks l r1 ⇒ Row.Cons l a r1 r2 ⇒ Proxy l → Record r2 → Record r1
0 commit comments