@@ -18,8 +18,7 @@ module Data.Codec.Argonaut.Sum
1818 , sumFlatWith
1919 , sumWith
2020 , taggedSum
21- )
22- where
21+ ) where
2322
2423import Prelude
2524
@@ -110,12 +109,15 @@ taggedSum name printTag parseTag f g = Codec.codec decodeCase encodeCase
110109
111110data Encoding
112111 = EncodeNested
113- { unwrapSingleArguments ∷ Boolean }
112+ { unwrapSingleArguments ∷ Boolean
113+ , mapTag ∷ String → String
114+ }
114115 | EncodeTagged
115116 { tagKey ∷ String
116117 , valuesKey ∷ String
117118 , omitEmptyArguments ∷ Boolean
118119 , unwrapSingleArguments ∷ Boolean
120+ , mapTag ∷ String → String
119121 }
120122
121123defaultEncoding ∷ Encoding
@@ -124,6 +126,7 @@ defaultEncoding = EncodeTagged
124126 , valuesKey: " values"
125127 , unwrapSingleArguments: false
126128 , omitEmptyArguments: false
129+ , mapTag: identity
127130 }
128131
129132-- ------------------------------------------------------------------------------
@@ -301,9 +304,10 @@ checkTag tagKey obj expectedTag = do
301304 $ TypeMismatch (" Expecting tag `" <> expectedTag <> " `, got `" <> tag <> " `" )
302305
303306parseNoFields ∷ Encoding → Json → String → Either JsonDecodeError Unit
304- parseNoFields encoding json expectedTag =
307+ parseNoFields encoding json expectedTagRaw =
305308 case encoding of
306- EncodeNested {} → do
309+ EncodeNested { mapTag } → do
310+ let expectedTag = mapTag expectedTagRaw ∷ String
307311 obj ← CA .decode jobject json
308312 val ←
309313 ( Obj .lookup expectedTag obj # note (TypeMismatch (" Expecting a property `" <> expectedTag <> " `" ))
@@ -313,7 +317,8 @@ parseNoFields encoding json expectedTag =
313317 $ Left
314318 $ TypeMismatch " Expecting an empty array"
315319
316- EncodeTagged { tagKey, valuesKey, omitEmptyArguments } → do
320+ EncodeTagged { tagKey, valuesKey, omitEmptyArguments, mapTag } → do
321+ let expectedTag = mapTag expectedTagRaw ∷ String
317322 obj ← CA .decode jobject json
318323 checkTag tagKey obj expectedTag
319324 when (not omitEmptyArguments) do
@@ -327,8 +332,9 @@ parseNoFields encoding json expectedTag =
327332 $ TypeMismatch " Expecting an empty array"
328333
329334parseSingleField ∷ 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
332338 obj ← CA .decode jobject json
333339 val ←
334340 ( Obj .lookup expectedTag obj # note (TypeMismatch (" Expecting a property `" <> expectedTag <> " `" ))
@@ -341,7 +347,8 @@ parseSingleField encoding json expectedTag = case encoding of
341347 [ head ] → pure head
342348 _ → Left $ TypeMismatch " Expecting exactly one element"
343349
344- EncodeTagged { tagKey, valuesKey, unwrapSingleArguments } → do
350+ EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, mapTag } → do
351+ let expectedTag = mapTag expectedTagRaw ∷ String
345352 obj ← CA .decode jobject json
346353 checkTag tagKey obj expectedTag
347354 val ←
@@ -357,16 +364,18 @@ parseSingleField encoding json expectedTag = case encoding of
357364 _ → Left $ TypeMismatch " Expecting exactly one element"
358365
359366parseManyFields ∷ Encoding → Json → String → Either JsonDecodeError (Array Json )
360- parseManyFields encoding json expectedTag =
367+ parseManyFields encoding json expectedTagRaw =
361368 case encoding of
362- EncodeNested {} → do
369+ EncodeNested { mapTag } → do
370+ let expectedTag = mapTag expectedTagRaw ∷ String
363371 obj ← CA .decode jobject json
364372 val ←
365373 ( Obj .lookup expectedTag obj # note (TypeMismatch (" Expecting a property `" <> expectedTag <> " `" ))
366374 ) ∷ _ Json
367375 CA .decode CA .jarray val
368376
369- EncodeTagged { tagKey, valuesKey } → do
377+ EncodeTagged { tagKey, valuesKey, mapTag } → do
378+ let expectedTag = mapTag expectedTagRaw ∷ String
370379 obj ← CA .decode jobject json
371380 checkTag tagKey obj expectedTag
372381 val ←
@@ -376,10 +385,11 @@ parseManyFields encoding json expectedTag =
376385 CA .decode CA .jarray val
377386
378387encodeSumCase ∷ Encoding → String → Array Json → Json
379- encodeSumCase encoding tag jsons =
388+ encodeSumCase encoding rawTag jsons =
380389 case encoding of
381- EncodeNested { unwrapSingleArguments } →
390+ EncodeNested { unwrapSingleArguments, mapTag } →
382391 let
392+ tag = mapTag rawTag ∷ String
383393 val = case jsons of
384394 [] → CA .encode CA .jarray []
385395 [ json ] | unwrapSingleArguments → json
@@ -389,8 +399,9 @@ encodeSumCase encoding tag jsons =
389399 [ tag /\ val
390400 ]
391401
392- EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, omitEmptyArguments } →
402+ EncodeTagged { tagKey, valuesKey, unwrapSingleArguments, omitEmptyArguments, mapTag } →
393403 let
404+ tag = mapTag rawTag ∷ String
394405 tagEntry =
395406 Just (tagKey /\ CA .encode CA .string tag) ∷ Maybe (String /\ Json )
396407 valEntry =
@@ -412,7 +423,7 @@ defaultFlatEncoding = { tag: Proxy }
412423sumFlat ∷ ∀ r rep a . GFlatCases " tag" r rep ⇒ Generic a rep ⇒ String → Record r → JsonCodec a
413424sumFlat = sumFlatWith defaultFlatEncoding
414425
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
416427sumFlatWith _ name r =
417428 dimap from to $ codec' dec enc
418429 where
@@ -529,6 +540,39 @@ instance gFlatCasesSum ∷
529540 rhs = gFlatCasesDecode @tag r2 tagged ∷ _ rhs
530541 (Inl <$> lhs) <|> (Inr <$> rhs)
531542
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+
532576-- | Same as `Record.delete` but deleting only happens at the type level
533577-- | and the value is left untouched.
534578unsafeDelete ∷ ∀ 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