@@ -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 =
@@ -404,27 +415,31 @@ encodeSumCase encoding tag jsons =
404
415
405
416
type FlatEncoding (tag ∷ Symbol ) =
406
417
{ tag ∷ Proxy tag
418
+ , mapTag ∷ String → String
407
419
}
408
420
409
421
defaultFlatEncoding ∷ FlatEncoding " tag"
410
- defaultFlatEncoding = { tag: Proxy }
422
+ defaultFlatEncoding =
423
+ { tag: Proxy
424
+ , mapTag: identity
425
+ }
411
426
412
427
sumFlat ∷ ∀ r rep a . GFlatCases " tag" r rep ⇒ Generic a rep ⇒ String → Record r → JsonCodec a
413
428
sumFlat = sumFlatWith defaultFlatEncoding
414
429
415
- sumFlatWith ∷ ∀ @tag r rep a . GFlatCases tag r rep ⇒ Generic a rep ⇒ FlatEncoding tag -> String → Record r → JsonCodec a
416
- sumFlatWith _ name r =
430
+ sumFlatWith ∷ ∀ @tag r rep a . GFlatCases tag r rep ⇒ Generic a rep ⇒ FlatEncoding tag → String → Record r → JsonCodec a
431
+ sumFlatWith encoding name r =
417
432
dimap from to $ codec' dec enc
418
433
where
419
- dec = gFlatCasesDecode @tag r >>> (lmap $ Named name)
420
- enc = gFlatCasesEncode @tag r
434
+ dec = gFlatCasesDecode @tag encoding r >>> (lmap $ Named name)
435
+ enc = gFlatCasesEncode @tag encoding r
421
436
422
437
class GFlatCases ∷ Symbol → Row Type → Type → Constraint
423
438
class
424
439
GFlatCases tag r rep
425
440
where
426
- gFlatCasesEncode ∷ Record r → rep → Json
427
- gFlatCasesDecode ∷ Record r → Json → Either JsonDecodeError rep
441
+ gFlatCasesEncode ∷ FlatEncoding tag → Record r → rep → Json
442
+ gFlatCasesDecode ∷ FlatEncoding tag → Record r → Json → Either JsonDecodeError rep
428
443
429
444
instance gFlatCasesConstructorNoArg ∷
430
445
( Row.Cons name Unit () rc
@@ -433,22 +448,23 @@ instance gFlatCasesConstructorNoArg ∷
433
448
, IsSymbol tag
434
449
) ⇒
435
450
GFlatCases tag rc (Constructor name NoArguments ) where
436
- gFlatCasesEncode ∷ Record rc → Constructor name NoArguments → Json
437
- gFlatCasesEncode _ (Constructor NoArguments ) =
451
+ gFlatCasesEncode ∷ FlatEncoding tag → Record rc → Constructor name NoArguments → Json
452
+ gFlatCasesEncode { mapTag } _ (Constructor NoArguments ) =
438
453
let
439
- name = reflectSymbol (Proxy @name) ∷ String
454
+ nameRaw = reflectSymbol (Proxy @name) ∷ String
455
+ name = mapTag nameRaw ∷ String
440
456
propCodec = CAR .record {} ∷ JPropCodec { }
441
457
propCodecWithTag = CA .recordProp (Proxy @tag) CA .string propCodec ∷ JPropCodec (Record rf )
442
458
codecWithTag = CA .object (" case " <> name) propCodecWithTag ∷ JsonCodec (Record rf )
443
459
rcWithTag = Record .insert (Proxy @tag) name {} ∷ Record rf
444
460
in
445
461
CA .encode codecWithTag rcWithTag
446
462
447
- gFlatCasesDecode ∷ Record rc → Json → Either JsonDecodeError (Constructor name NoArguments )
448
- gFlatCasesDecode _ json = do
463
+ gFlatCasesDecode ∷ FlatEncoding tag → Record rc → Json → Either JsonDecodeError (Constructor name NoArguments )
464
+ gFlatCasesDecode { mapTag } _ json = do
449
465
let
450
- name = reflectSymbol (Proxy @name) ∷ String
451
-
466
+ nameRaw = reflectSymbol (Proxy @name) ∷ String
467
+ name = mapTag nameRaw ∷ String
452
468
propCodec = CAR .record {} ∷ JPropCodec { }
453
469
propCodecWithTag = CA .recordProp (Proxy @tag) CA .string propCodec ∷ JPropCodec (Record rf )
454
470
codecWithTag = CA .object (" case " <> name) propCodecWithTag ∷ JsonCodec (Record rf )
@@ -469,21 +485,23 @@ instance gFlatCasesConstructorSingleArg ∷
469
485
, IsSymbol tag
470
486
) ⇒
471
487
GFlatCases tag rc (Constructor name (Argument (Record rf ))) where
472
- gFlatCasesEncode ∷ Record rc → Constructor name (Argument (Record rf )) → Json
473
- gFlatCasesEncode rc (Constructor (Argument rf)) =
488
+ gFlatCasesEncode ∷ FlatEncoding tag → Record rc → Constructor name (Argument (Record rf )) → Json
489
+ gFlatCasesEncode { mapTag } rc (Constructor (Argument rf)) =
474
490
let
475
- name = reflectSymbol (Proxy @name) ∷ String
491
+ nameRaw = reflectSymbol (Proxy @name) ∷ String
492
+ name = mapTag nameRaw ∷ String
476
493
propCodec = Record .get (Proxy @name) rc ∷ JPropCodec (Record rf )
477
494
propCodecWithTag = CA .recordProp (Proxy @tag) CA .string propCodec ∷ JPropCodec (Record rf' )
478
495
codecWithTag = CA .object (" case " <> name) propCodecWithTag ∷ JsonCodec (Record rf' )
479
496
rcWithTag = Record .insert (Proxy @tag) name rf ∷ Record rf'
480
497
in
481
498
CA .encode codecWithTag rcWithTag
482
499
483
- gFlatCasesDecode ∷ Record rc → Json → Either JsonDecodeError (Constructor name (Argument (Record rf )))
484
- gFlatCasesDecode rc json = do
500
+ gFlatCasesDecode ∷ FlatEncoding tag → Record rc → Json → Either JsonDecodeError (Constructor name (Argument (Record rf )))
501
+ gFlatCasesDecode { mapTag } rc json = do
485
502
let
486
- name = reflectSymbol (Proxy @name) ∷ String
503
+ nameRaw = reflectSymbol (Proxy @name) ∷ String
504
+ name = mapTag nameRaw ∷ String
487
505
propCodec = Record .get (Proxy @name) rc ∷ JPropCodec (Record rf )
488
506
propCodecWithTag = CA .recordProp (Proxy @tag) CA .string propCodec ∷ JPropCodec (Record rf' )
489
507
codecWithTag = CA .object (" case " <> name) propCodecWithTag ∷ JsonCodec (Record rf' )
@@ -507,28 +525,30 @@ instance gFlatCasesSum ∷
507
525
, IsSymbol name
508
526
) ⇒
509
527
GFlatCases tag r (Sum (Constructor name lhs ) rhs ) where
510
- gFlatCasesEncode ∷ Record r → Sum (Constructor name lhs ) rhs → Json
511
- gFlatCasesEncode r =
528
+ gFlatCasesEncode ∷ FlatEncoding tag → Record r → Sum (Constructor name lhs ) rhs → Json
529
+ gFlatCasesEncode encoding r =
512
530
let
513
531
codec = Record .get (Proxy @name) r ∷ codec
514
532
r1 = Record .insert (Proxy @name) codec {} ∷ Record r1
515
533
r2 = unsafeDelete (Proxy @name) r ∷ Record r2
516
534
in
517
535
case _ of
518
- Inl lhs → gFlatCasesEncode @tag r1 lhs
519
- Inr rhs → gFlatCasesEncode @tag r2 rhs
536
+ Inl lhs → gFlatCasesEncode @tag encoding r1 lhs
537
+ Inr rhs → gFlatCasesEncode @tag encoding r2 rhs
520
538
521
- gFlatCasesDecode ∷ Record r → Json → Either JsonDecodeError (Sum (Constructor name lhs ) rhs )
522
- gFlatCasesDecode r tagged = do
539
+ gFlatCasesDecode ∷ FlatEncoding tag → Record r → Json → Either JsonDecodeError (Sum (Constructor name lhs ) rhs )
540
+ gFlatCasesDecode encoding r tagged = do
523
541
let
524
542
codec = Record .get (Proxy @name) r ∷ codec
525
543
r1 = Record .insert (Proxy @name) codec {} ∷ Record r1
526
544
r2 = Record .delete (Proxy @name) r ∷ Record r2
527
545
let
528
- lhs = gFlatCasesDecode @tag r1 tagged ∷ _ (Constructor name lhs )
529
- rhs = gFlatCasesDecode @tag r2 tagged ∷ _ rhs
546
+ lhs = gFlatCasesDecode @tag encoding r1 tagged ∷ _ (Constructor name lhs )
547
+ rhs = gFlatCasesDecode @tag encoding r2 tagged ∷ _ rhs
530
548
(Inl <$> lhs) <|> (Inr <$> rhs)
531
549
550
+ -- ------------------------------------------------------------------------------
551
+
532
552
-- | Same as `Record.delete` but deleting only happens at the type level
533
553
-- | and the value is left untouched.
534
554
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