@@ -109,12 +109,15 @@ taggedSum name printTag parseTag f g = Codec.codec decodeCase encodeCase
109
109
110
110
data Encoding
111
111
= EncodeNested
112
- { unwrapSingleArguments ∷ Boolean }
112
+ { unwrapSingleArguments ∷ Boolean
113
+ , mapTag ∷ String → String
114
+ }
113
115
| EncodeTagged
114
116
{ tagKey ∷ String
115
117
, valuesKey ∷ String
116
118
, omitEmptyArguments ∷ Boolean
117
119
, unwrapSingleArguments ∷ Boolean
120
+ , mapTag ∷ String → String
118
121
}
119
122
120
123
defaultEncoding ∷ Encoding
@@ -123,6 +126,7 @@ defaultEncoding = EncodeTagged
123
126
, valuesKey: " values"
124
127
, unwrapSingleArguments: false
125
128
, omitEmptyArguments: false
129
+ , mapTag: identity
126
130
}
127
131
128
132
-- ------------------------------------------------------------------------------
@@ -312,9 +316,10 @@ checkTag tagKey obj expectedTag = do
312
316
(Left UnmatchedCase )
313
317
314
318
parseNoFields ∷ Encoding → Json → String → Either Err Unit
315
- parseNoFields encoding json expectedTag =
319
+ parseNoFields encoding json expectedTagRaw =
316
320
case encoding of
317
- EncodeNested {} → do
321
+ EncodeNested { mapTag } → do
322
+ let expectedTag = mapTag expectedTagRaw ∷ String
318
323
obj ← lmap JErr $ CA .decode jobject json
319
324
val ←
320
325
( Obj .lookup expectedTag obj # note UnmatchedCase
@@ -325,7 +330,8 @@ parseNoFields encoding json expectedTag =
325
330
(JErr $ TypeMismatch " Expecting an empty array" )
326
331
pure unit
327
332
328
- EncodeTagged { tagKey, valuesKey, omitEmptyArguments } → do
333
+ EncodeTagged { tagKey, valuesKey, omitEmptyArguments, mapTag } → do
334
+ let expectedTag = mapTag expectedTagRaw ∷ String
329
335
obj ← lmap JErr $ CA .decode jobject json
330
336
checkTag tagKey obj expectedTag
331
337
when (not omitEmptyArguments) do
@@ -340,8 +346,9 @@ parseNoFields encoding json expectedTag =
340
346
pure unit
341
347
342
348
parseSingleField ∷ Encoding → Json → String → Either Err Json
343
- parseSingleField encoding json expectedTag = case encoding of
344
- EncodeNested { unwrapSingleArguments } → do
349
+ parseSingleField encoding json expectedTagRaw = case encoding of
350
+ EncodeNested { unwrapSingleArguments, mapTag } → do
351
+ let expectedTag = mapTag expectedTagRaw ∷ String
345
352
obj ← lmap JErr $ CA .decode jobject json
346
353
val ←
347
354
( Obj .lookup expectedTag obj # note UnmatchedCase
@@ -354,7 +361,8 @@ parseSingleField encoding json expectedTag = case encoding of
354
361
[ head ] → pure head
355
362
_ → Left $ JErr $ TypeMismatch " Expecting exactly one element"
356
363
357
- EncodeTagged { tagKey, valuesKey, unwrapSingleArguments } → do
364
+ EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, mapTag } → do
365
+ let expectedTag = mapTag expectedTagRaw ∷ String
358
366
obj ← lmap JErr $ CA .decode jobject json
359
367
checkTag tagKey obj expectedTag
360
368
val ←
@@ -370,16 +378,18 @@ parseSingleField encoding json expectedTag = case encoding of
370
378
_ → Left $ JErr $ TypeMismatch " Expecting exactly one element"
371
379
372
380
parseManyFields ∷ Encoding → Json → String → Either Err (Array Json )
373
- parseManyFields encoding json expectedTag =
381
+ parseManyFields encoding json expectedTagRaw =
374
382
case encoding of
375
- EncodeNested {} → do
383
+ EncodeNested { mapTag } → do
384
+ let expectedTag = mapTag expectedTagRaw ∷ String
376
385
obj ← lmap JErr $ CA .decode jobject json
377
386
val ←
378
387
( Obj .lookup expectedTag obj # note UnmatchedCase
379
388
) ∷ _ Json
380
389
lmap JErr $ CA .decode CA .jarray val
381
390
382
- EncodeTagged { tagKey, valuesKey } → do
391
+ EncodeTagged { tagKey, valuesKey, mapTag } → do
392
+ let expectedTag = mapTag expectedTagRaw ∷ String
383
393
obj ← lmap JErr $ CA .decode jobject json
384
394
checkTag tagKey obj expectedTag
385
395
val ←
@@ -389,10 +399,11 @@ parseManyFields encoding json expectedTag =
389
399
lmap JErr $ CA .decode CA .jarray val
390
400
391
401
encodeSumCase ∷ Encoding → String → Array Json → Json
392
- encodeSumCase encoding tag jsons =
402
+ encodeSumCase encoding rawTag jsons =
393
403
case encoding of
394
- EncodeNested { unwrapSingleArguments } →
404
+ EncodeNested { unwrapSingleArguments, mapTag } →
395
405
let
406
+ tag = mapTag rawTag ∷ String
396
407
val = case jsons of
397
408
[] → CA .encode CA .jarray []
398
409
[ json ] | unwrapSingleArguments → json
@@ -402,8 +413,9 @@ encodeSumCase encoding tag jsons =
402
413
[ tag /\ val
403
414
]
404
415
405
- EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, omitEmptyArguments } →
416
+ EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, omitEmptyArguments, mapTag } →
406
417
let
418
+ tag = mapTag rawTag ∷ String
407
419
tagEntry =
408
420
Just (tagKey /\ CA .encode CA .string tag) ∷ Maybe (String /\ Json )
409
421
valEntry =
@@ -417,27 +429,31 @@ encodeSumCase encoding tag jsons =
417
429
418
430
type FlatEncoding (tag ∷ Symbol ) =
419
431
{ tag ∷ Proxy tag
432
+ , mapTag ∷ String → String
420
433
}
421
434
422
435
defaultFlatEncoding ∷ FlatEncoding " tag"
423
- defaultFlatEncoding = { tag: Proxy }
436
+ defaultFlatEncoding =
437
+ { tag: Proxy
438
+ , mapTag: identity
439
+ }
424
440
425
441
sumFlat ∷ ∀ r rep a . GFlatCases " tag" r rep ⇒ Generic a rep ⇒ String → Record r → JsonCodec a
426
442
sumFlat = sumFlatWith defaultFlatEncoding
427
443
428
444
sumFlatWith ∷ ∀ @tag r rep a . GFlatCases tag r rep ⇒ Generic a rep ⇒ FlatEncoding tag → String → Record r → JsonCodec a
429
- sumFlatWith _ name r =
445
+ sumFlatWith encoding name r =
430
446
dimap from to $ codec' dec enc
431
447
where
432
- dec = gFlatCasesDecode @tag r >>> (lmap $ finalizeError name)
433
- enc = gFlatCasesEncode @tag r
448
+ dec = gFlatCasesDecode @tag encoding r >>> (lmap $ finalizeError name)
449
+ enc = gFlatCasesEncode @tag encoding r
434
450
435
451
class GFlatCases ∷ Symbol → Row Type → Type → Constraint
436
452
class
437
453
GFlatCases tag r rep
438
454
where
439
- gFlatCasesEncode ∷ Record r → rep → Json
440
- gFlatCasesDecode ∷ Record r → Json → Either Err rep
455
+ gFlatCasesEncode ∷ FlatEncoding tag → Record r → rep → Json
456
+ gFlatCasesDecode ∷ FlatEncoding tag → Record r → Json → Either Err rep
441
457
442
458
instance gFlatCasesConstructorNoArg ∷
443
459
( Row.Cons name Unit () rc
@@ -446,21 +462,23 @@ instance gFlatCasesConstructorNoArg ∷
446
462
, IsSymbol tag
447
463
) ⇒
448
464
GFlatCases tag rc (Constructor name NoArguments ) where
449
- gFlatCasesEncode ∷ Record rc → Constructor name NoArguments → Json
450
- gFlatCasesEncode _ (Constructor NoArguments ) =
465
+ gFlatCasesEncode ∷ FlatEncoding tag → Record rc → Constructor name NoArguments → Json
466
+ gFlatCasesEncode { mapTag } _ (Constructor NoArguments ) =
451
467
let
452
- name = reflectSymbol (Proxy @name) ∷ String
468
+ nameRaw = reflectSymbol (Proxy @name) ∷ String
469
+ name = mapTag nameRaw ∷ String
453
470
propCodec = CAR .record {} ∷ JPropCodec { }
454
471
propCodecWithTag = CA .recordProp (Proxy @tag) CA .string propCodec ∷ JPropCodec (Record rf )
455
472
codecWithTag = CA .object (" case " <> name) propCodecWithTag ∷ JsonCodec (Record rf )
456
473
rcWithTag = Record .insert (Proxy @tag) name {} ∷ Record rf
457
474
in
458
475
CA .encode codecWithTag rcWithTag
459
476
460
- gFlatCasesDecode ∷ Record rc → Json → Either Err (Constructor name NoArguments )
461
- gFlatCasesDecode _ json = do
477
+ gFlatCasesDecode ∷ FlatEncoding tag → Record rc → Json → Either Err (Constructor name NoArguments )
478
+ gFlatCasesDecode { mapTag } _ json = do
462
479
let
463
- name = reflectSymbol (Proxy @name) ∷ String
480
+ nameRaw = reflectSymbol (Proxy @name) ∷ String
481
+ name = mapTag nameRaw ∷ String
464
482
tag = reflectSymbol (Proxy @tag) ∷ String
465
483
466
484
obj ← lmap JErr $ CA .decode jobject json
@@ -469,6 +487,7 @@ instance gFlatCasesConstructorNoArg ∷
469
487
470
488
pure (Constructor NoArguments )
471
489
490
+
472
491
instance gFlatCasesConstructorSingleArg ∷
473
492
( Row.Cons name (JPropCodec (Record rf )) () rc
474
493
, Row.Lacks tag rf
@@ -477,27 +496,31 @@ instance gFlatCasesConstructorSingleArg ∷
477
496
, IsSymbol tag
478
497
) ⇒
479
498
GFlatCases tag rc (Constructor name (Argument (Record rf ))) where
480
- gFlatCasesEncode ∷ Record rc → Constructor name (Argument (Record rf )) → Json
481
- gFlatCasesEncode rc (Constructor (Argument rf)) =
499
+ gFlatCasesEncode ∷ FlatEncoding tag → Record rc → Constructor name (Argument (Record rf )) → Json
500
+ gFlatCasesEncode { mapTag } rc (Constructor (Argument rf)) =
482
501
let
483
- name = reflectSymbol (Proxy @name) ∷ String
502
+ nameRaw = reflectSymbol (Proxy @name) ∷ String
503
+ name = mapTag nameRaw ∷ String
484
504
propCodec = Record .get (Proxy @name) rc ∷ JPropCodec (Record rf )
485
505
propCodecWithTag = CA .recordProp (Proxy @tag) CA .string propCodec ∷ JPropCodec (Record rf' )
486
506
codecWithTag = CA .object (" case " <> name) propCodecWithTag ∷ JsonCodec (Record rf' )
487
507
rcWithTag = Record .insert (Proxy @tag) name rf ∷ Record rf'
488
508
in
489
509
CA .encode codecWithTag rcWithTag
490
510
491
- gFlatCasesDecode ∷ Record rc → Json → Either Err (Constructor name (Argument (Record rf )))
492
- gFlatCasesDecode rc json = do
511
+
512
+ gFlatCasesDecode ∷ FlatEncoding tag → Record rc → Json → Either Err (Constructor name (Argument (Record rf )))
513
+ gFlatCasesDecode { mapTag } rc json = do
493
514
let
494
- name = reflectSymbol (Proxy @name) ∷ String
515
+ nameRaw = reflectSymbol (Proxy @name) ∷ String
516
+ name = mapTag nameRaw ∷ String
495
517
tag = reflectSymbol (Proxy @tag) ∷ String
518
+
496
519
497
520
obj ← lmap JErr $ CA .decode jobject json
498
521
499
522
checkTag tag obj name
500
-
523
+
501
524
let
502
525
propCodec = Record .get (Proxy @name) rc ∷ JPropCodec (Record rf )
503
526
codec = CA .object (" case " <> name) propCodec ∷ JsonCodec (Record rf )
@@ -516,31 +539,33 @@ instance gFlatCasesSum ∷
516
539
, IsSymbol name
517
540
) ⇒
518
541
GFlatCases tag r (Sum (Constructor name lhs ) rhs ) where
519
- gFlatCasesEncode ∷ Record r → Sum (Constructor name lhs ) rhs → Json
520
- gFlatCasesEncode r =
542
+ gFlatCasesEncode ∷ FlatEncoding tag → Record r → Sum (Constructor name lhs ) rhs → Json
543
+ gFlatCasesEncode encoding r =
521
544
let
522
545
codec = Record .get (Proxy @name) r ∷ codec
523
546
r1 = Record .insert (Proxy @name) codec {} ∷ Record r1
524
547
r2 = unsafeDelete (Proxy @name) r ∷ Record r2
525
548
in
526
549
case _ of
527
- Inl lhs → gFlatCasesEncode @tag r1 lhs
528
- Inr rhs → gFlatCasesEncode @tag r2 rhs
550
+ Inl lhs → gFlatCasesEncode @tag encoding r1 lhs
551
+ Inr rhs → gFlatCasesEncode @tag encoding r2 rhs
529
552
530
- gFlatCasesDecode ∷ Record r → Json → Either Err (Sum (Constructor name lhs ) rhs )
531
- gFlatCasesDecode r tagged = do
553
+ gFlatCasesDecode ∷ FlatEncoding tag -> Record r → Json → Either Err (Sum (Constructor name lhs ) rhs )
554
+ gFlatCasesDecode encoding r tagged = do
532
555
let
533
556
codec = Record .get (Proxy @name) r ∷ codec
534
557
r1 = Record .insert (Proxy @name) codec {} ∷ Record r1
535
558
r2 = Record .delete (Proxy @name) r ∷ Record r2
536
559
let
537
- lhs _ = gFlatCasesDecode @tag r1 tagged ∷ _ (Constructor name lhs )
538
- rhs _ = gFlatCasesDecode @tag r2 tagged ∷ _ rhs
560
+ lhs _ = gFlatCasesDecode @tag encoding r1 tagged ∷ _ (Constructor name lhs )
561
+ rhs _ = gFlatCasesDecode @tag encoding r2 tagged ∷ _ rhs
539
562
case lhs unit of
540
563
Left UnmatchedCase → Inr <$> rhs unit
541
564
Left (JErr err) → Left (JErr err)
542
565
Right val → Right (Inl val)
543
566
567
+ -- ------------------------------------------------------------------------------
568
+
544
569
-- | Same as `Record.delete` but deleting only happens at the type level
545
570
-- | and the value is left untouched.
546
571
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