@@ -14,8 +14,7 @@ import Data.Aeson.Types (Parser)
14
14
import qualified Data.HashMap.Strict as HM
15
15
import qualified Data.Vector as V
16
16
import Generics.SOP
17
- import Generics.SOP.JSON (JsonInfo (.. ), JsonOptions (.. ), Tag (.. ), defaultJsonOptions ,
18
- jsonInfo )
17
+ import Generics.SOP.JSON (JsonInfo (.. ), JsonOptions (.. ), Tag (.. ), defaultJsonOptions )
19
18
20
19
import Cardano.Wallet.API.Response.JSend (ResponseStatus (.. ))
21
20
import Cardano.Wallet.Util (mkJsonKey )
@@ -42,24 +41,46 @@ allpf = Proxy
42
41
-- JSON encoding/decoding
43
42
--
44
43
45
- -- | Returns `JsonInfo` for type (from `json-sop` package)
46
- -- for representing a type in a JSend format.
47
- jsendInfo
48
- :: forall a . (HasDatatypeInfo a , SListI (Code a ))
49
- => Proxy a -> NP JsonInfo (Code a )
50
- jsendInfo pa = jsonInfo pa $ defaultJsonOptions
51
- { jsonFieldName = const mkJsonKey
52
- }
53
-
54
44
-- | Generic method which makes JSON `Value` from a Haskell value in
55
45
-- JSend format.
56
46
gtoJsend
57
47
:: forall a . (Generic a , HasDatatypeInfo a , All2 ToJSON (Code a ))
58
48
=> ResponseStatus -> a -> Value
59
- gtoJsend rs a = hcollapse $
60
- hcliftA2 allpt (gtoJsend' rs)
61
- (jsendInfo (Proxy :: Proxy a ))
62
- (unSOP $ from a)
49
+ gtoJsend rs a =
50
+ hcollapse $
51
+ hcliftA2 allpt (gtoJsend' rs)
52
+ (jsendInfo (Proxy :: Proxy a ) jsendOptions)
53
+ (unSOP $ from a)
54
+
55
+ -- | Our custom naming options
56
+ jsendOptions :: JsonOptions
57
+ jsendOptions = defaultJsonOptions
58
+ { jsonFieldName = const mkJsonKey
59
+ }
60
+
61
+ -- | Slightly modified version compared to Generics.SOP.JSON, we also tag
62
+ -- single-constructor (ADT with one constructor and newtype) because we
63
+ -- rely on that information to wrap the corresponding json in a jsend payload.
64
+ jsendInfo :: forall a . (HasDatatypeInfo a , SListI (Code a ))
65
+ => Proxy a -> JsonOptions -> NP JsonInfo (Code a )
66
+ jsendInfo pa opts =
67
+ case datatypeInfo pa of
68
+ Newtype _ t _ -> JsonOne (Tag $ jsonTagName opts t) :* Nil
69
+ ADT _ n cs -> hliftA (jsonInfoFor opts n (Tag . jsonTagName opts)) cs
70
+
71
+ -- Extracted from Generics.SOP.JSON
72
+ jsonInfoFor :: forall xs . JsonOptions -> DatatypeName -> (ConstructorName -> Tag ) -> ConstructorInfo xs -> JsonInfo xs
73
+ jsonInfoFor _ _ tag (Infix n _ _) = JsonMultiple (tag n)
74
+ jsonInfoFor _ _ tag (Constructor n) =
75
+ case shape :: Shape xs of
76
+ ShapeNil -> JsonZero n
77
+ ShapeCons ShapeNil -> JsonOne (tag n)
78
+ _ -> JsonMultiple (tag n)
79
+ jsonInfoFor opts d tag (Record n fields) =
80
+ JsonRecord (tag n) (hliftA jfieldName fields)
81
+ where
82
+ jfieldName :: FieldInfo a -> K String a
83
+ jfieldName (FieldInfo name) = K (jsonFieldName opts d name)
63
84
64
85
gtoJsend'
65
86
:: All ToJSON xs
@@ -79,7 +100,7 @@ gtoJsend' rs (JsonRecord tag fields) cs =
79
100
gparseJsend
80
101
:: forall a . (Generic a , HasDatatypeInfo a , All2 FromJSON (Code a ))
81
102
=> Value -> Parser a
82
- gparseJsend v = to <$> gparseJsend' v (jsendInfo (Proxy :: Proxy a ))
103
+ gparseJsend v = to <$> gparseJsend' v (jsendInfo (Proxy :: Proxy a ) jsendOptions )
83
104
84
105
gparseJsend'
85
106
:: forall (xss :: [[* ]]). All2 FromJSON xss
0 commit comments