Skip to content

Commit b2b6559

Browse files
committed
Merge branch 'master' into error-improvements
2 parents cb6b1d4 + b192e34 commit b2b6559

File tree

2 files changed

+207
-49
lines changed

2 files changed

+207
-49
lines changed

src/Data/Codec/Argonaut/Sum.purs

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,15 @@ taggedSum name printTag parseTag f g = Codec.codec decodeCase encodeCase
109109

110110
data Encoding
111111
= EncodeNested
112-
{ unwrapSingleArguments Boolean }
112+
{ unwrapSingleArguments Boolean
113+
, mapTag String String
114+
}
113115
| EncodeTagged
114116
{ tagKey String
115117
, valuesKey String
116118
, omitEmptyArguments Boolean
117119
, unwrapSingleArguments Boolean
120+
, mapTag String String
118121
}
119122

120123
defaultEncoding Encoding
@@ -123,6 +126,7 @@ defaultEncoding = EncodeTagged
123126
, valuesKey: "values"
124127
, unwrapSingleArguments: false
125128
, omitEmptyArguments: false
129+
, mapTag: identity
126130
}
127131

128132
--------------------------------------------------------------------------------
@@ -312,9 +316,10 @@ checkTag tagKey obj expectedTag = do
312316
(Left UnmatchedCase)
313317

314318
parseNoFields Encoding Json String Either Err Unit
315-
parseNoFields encoding json expectedTag =
319+
parseNoFields encoding json expectedTagRaw =
316320
case encoding of
317-
EncodeNested {} → do
321+
EncodeNested { mapTag } → do
322+
let expectedTag = mapTag expectedTagRaw String
318323
obj ← lmap JErr $ CA.decode jobject json
319324
val ←
320325
( Obj.lookup expectedTag obj # note UnmatchedCase
@@ -325,7 +330,8 @@ parseNoFields encoding json expectedTag =
325330
(JErr $ TypeMismatch "Expecting an empty array")
326331
pure unit
327332

328-
EncodeTagged { tagKey, valuesKey, omitEmptyArguments } → do
333+
EncodeTagged { tagKey, valuesKey, omitEmptyArguments, mapTag } → do
334+
let expectedTag = mapTag expectedTagRaw String
329335
obj ← lmap JErr $ CA.decode jobject json
330336
checkTag tagKey obj expectedTag
331337
when (not omitEmptyArguments) do
@@ -340,8 +346,9 @@ parseNoFields encoding json expectedTag =
340346
pure unit
341347

342348
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
345352
obj ← lmap JErr $ CA.decode jobject json
346353
val ←
347354
( Obj.lookup expectedTag obj # note UnmatchedCase
@@ -354,7 +361,8 @@ parseSingleField encoding json expectedTag = case encoding of
354361
[ head ] → pure head
355362
_ → Left $ JErr $ TypeMismatch "Expecting exactly one element"
356363

357-
EncodeTagged { tagKey, valuesKey, unwrapSingleArguments } → do
364+
EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, mapTag } → do
365+
let expectedTag = mapTag expectedTagRaw String
358366
obj ← lmap JErr $ CA.decode jobject json
359367
checkTag tagKey obj expectedTag
360368
val ←
@@ -370,16 +378,18 @@ parseSingleField encoding json expectedTag = case encoding of
370378
_ → Left $ JErr $ TypeMismatch "Expecting exactly one element"
371379

372380
parseManyFields Encoding Json String Either Err (Array Json)
373-
parseManyFields encoding json expectedTag =
381+
parseManyFields encoding json expectedTagRaw =
374382
case encoding of
375-
EncodeNested {} → do
383+
EncodeNested { mapTag } → do
384+
let expectedTag = mapTag expectedTagRaw String
376385
obj ← lmap JErr $ CA.decode jobject json
377386
val ←
378387
( Obj.lookup expectedTag obj # note UnmatchedCase
379388
) _ Json
380389
lmap JErr $ CA.decode CA.jarray val
381390

382-
EncodeTagged { tagKey, valuesKey } → do
391+
EncodeTagged { tagKey, valuesKey, mapTag } → do
392+
let expectedTag = mapTag expectedTagRaw String
383393
obj ← lmap JErr $ CA.decode jobject json
384394
checkTag tagKey obj expectedTag
385395
val ←
@@ -389,10 +399,11 @@ parseManyFields encoding json expectedTag =
389399
lmap JErr $ CA.decode CA.jarray val
390400

391401
encodeSumCase Encoding String Array Json Json
392-
encodeSumCase encoding tag jsons =
402+
encodeSumCase encoding rawTag jsons =
393403
case encoding of
394-
EncodeNested { unwrapSingleArguments } →
404+
EncodeNested { unwrapSingleArguments, mapTag } →
395405
let
406+
tag = mapTag rawTag String
396407
val = case jsons of
397408
[]CA.encode CA.jarray []
398409
[ json ] | unwrapSingleArguments → json
@@ -402,8 +413,9 @@ encodeSumCase encoding tag jsons =
402413
[ tag /\ val
403414
]
404415

405-
EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, omitEmptyArguments } →
416+
EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, omitEmptyArguments, mapTag } →
406417
let
418+
tag = mapTag rawTag String
407419
tagEntry =
408420
Just (tagKey /\ CA.encode CA.string tag) Maybe (String /\ Json)
409421
valEntry =
@@ -417,27 +429,31 @@ encodeSumCase encoding tag jsons =
417429

418430
type FlatEncoding (tagSymbol) =
419431
{ tag Proxy tag
432+
, mapTag String String
420433
}
421434

422435
defaultFlatEncoding FlatEncoding "tag"
423-
defaultFlatEncoding = { tag: Proxy }
436+
defaultFlatEncoding =
437+
{ tag: Proxy
438+
, mapTag: identity
439+
}
424440

425441
sumFlat r rep a. GFlatCases "tag" r rep Generic a rep String Record r JsonCodec a
426442
sumFlat = sumFlatWith defaultFlatEncoding
427443

428444
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 =
430446
dimap from to $ codec' dec enc
431447
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
434450

435451
class GFlatCasesSymbol Row Type Type Constraint
436452
class
437453
GFlatCases tag r rep
438454
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
441457

442458
instance gFlatCasesConstructorNoArg
443459
( Row.Cons name Unit () rc
@@ -446,21 +462,23 @@ instance gFlatCasesConstructorNoArg ∷
446462
, IsSymbol tag
447463
)
448464
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) =
451467
let
452-
name = reflectSymbol (Proxy @name) String
468+
nameRaw = reflectSymbol (Proxy @name) String
469+
name = mapTag nameRaw String
453470
propCodec = CAR.record {} JPropCodec {}
454471
propCodecWithTag = CA.recordProp (Proxy @tag) CA.string propCodec JPropCodec (Record rf)
455472
codecWithTag = CA.object ("case " <> name) propCodecWithTag JsonCodec (Record rf)
456473
rcWithTag = Record.insert (Proxy @tag) name {} Record rf
457474
in
458475
CA.encode codecWithTag rcWithTag
459476

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
462479
let
463-
name = reflectSymbol (Proxy @name) String
480+
nameRaw = reflectSymbol (Proxy @name) String
481+
name = mapTag nameRaw String
464482
tag = reflectSymbol (Proxy @tag) String
465483

466484
obj ← lmap JErr $ CA.decode jobject json
@@ -469,6 +487,7 @@ instance gFlatCasesConstructorNoArg ∷
469487

470488
pure (Constructor NoArguments)
471489

490+
472491
instance gFlatCasesConstructorSingleArg
473492
( Row.Cons name (JPropCodec (Record rf)) () rc
474493
, Row.Lacks tag rf
@@ -477,27 +496,31 @@ instance gFlatCasesConstructorSingleArg ∷
477496
, IsSymbol tag
478497
)
479498
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)) =
482501
let
483-
name = reflectSymbol (Proxy @name) String
502+
nameRaw = reflectSymbol (Proxy @name) String
503+
name = mapTag nameRaw String
484504
propCodec = Record.get (Proxy @name) rc JPropCodec (Record rf)
485505
propCodecWithTag = CA.recordProp (Proxy @tag) CA.string propCodec JPropCodec (Record rf')
486506
codecWithTag = CA.object ("case " <> name) propCodecWithTag JsonCodec (Record rf')
487507
rcWithTag = Record.insert (Proxy @tag) name rf Record rf'
488508
in
489509
CA.encode codecWithTag rcWithTag
490510

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
493514
let
494-
name = reflectSymbol (Proxy @name) String
515+
nameRaw = reflectSymbol (Proxy @name) String
516+
name = mapTag nameRaw String
495517
tag = reflectSymbol (Proxy @tag) String
518+
496519

497520
obj ← lmap JErr $ CA.decode jobject json
498521

499522
checkTag tag obj name
500-
523+
501524
let
502525
propCodec = Record.get (Proxy @name) rc JPropCodec (Record rf)
503526
codec = CA.object ("case " <> name) propCodec JsonCodec (Record rf)
@@ -516,31 +539,33 @@ instance gFlatCasesSum ∷
516539
, IsSymbol name
517540
)
518541
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 =
521544
let
522545
codec = Record.get (Proxy @name) r codec
523546
r1 = Record.insert (Proxy @name) codec {} Record r1
524547
r2 = unsafeDelete (Proxy @name) r Record r2
525548
in
526549
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
529552

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
532555
let
533556
codec = Record.get (Proxy @name) r codec
534557
r1 = Record.insert (Proxy @name) codec {} Record r1
535558
r2 = Record.delete (Proxy @name) r Record r2
536559
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
539562
case lhs unit of
540563
Left UnmatchedCaseInr <$> rhs unit
541564
Left (JErr err) → Left (JErr err)
542565
Right val → Right (Inl val)
543566

567+
--------------------------------------------------------------------------------
568+
544569
-- | Same as `Record.delete` but deleting only happens at the type level
545570
-- | and the value is left untouched.
546571
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

Comments
 (0)