|
1 |
| -module Data.Argonaut.Decode.Generic ( |
2 |
| - class DecodeRep, |
3 |
| - class DecodeRepArgs, |
4 |
| - class DecodeLiteral, |
5 |
| - decodeRep, |
6 |
| - decodeRepWith, |
7 |
| - decodeRepArgs, |
8 |
| - genericDecodeJson, |
9 |
| - genericDecodeJsonWith, |
10 |
| - decodeLiteralSum, |
11 |
| - decodeLiteralSumWithTransform, |
12 |
| - decodeLiteral |
13 |
| -) where |
| 1 | +module Data.Argonaut.Decode.Generic |
| 2 | + ( class DecodeRep |
| 3 | + , class DecodeRepArgs |
| 4 | + , class DecodeLiteral |
| 5 | + , decodeRep |
| 6 | + , decodeRepWith |
| 7 | + , decodeRepArgs |
| 8 | + , genericDecodeJson |
| 9 | + , genericDecodeJsonWith |
| 10 | + , decodeLiteralSum |
| 11 | + , decodeLiteralSumWithTransform |
| 12 | + , decodeLiteral |
| 13 | + ) where |
14 | 14 |
|
15 | 15 | import Prelude
|
16 | 16 |
|
@@ -40,90 +40,94 @@ instance decodeRepNoConstructors :: DecodeRep Rep.NoConstructors where
|
40 | 40 | instance decodeRepSum :: (DecodeRep a, DecodeRep b) => DecodeRep (Rep.Sum a b) where
|
41 | 41 | decodeRepWith e j = Rep.Inl <$> decodeRepWith e j <|> Rep.Inr <$> decodeRepWith e j
|
42 | 42 |
|
43 |
| -withTag :: |
44 |
| - Encoding -> |
45 |
| - Json -> |
46 |
| - String -> |
47 |
| - Either JsonDecodeError |
48 |
| - { tag :: String |
49 |
| - , decodingErr :: JsonDecodeError -> JsonDecodeError |
50 |
| - } |
| 43 | +withTag |
| 44 | + :: Encoding |
| 45 | + -> Json |
| 46 | + -> String |
| 47 | + -> Either JsonDecodeError |
| 48 | + { tag :: String |
| 49 | + , decodingErr :: JsonDecodeError -> JsonDecodeError |
| 50 | + } |
51 | 51 | withTag e j name = do
|
52 | 52 | let decodingErr = Named name
|
53 | 53 | jObj <- note (decodingErr $ TypeMismatch "Object") (toObject j)
|
54 | 54 | jTag <- note (decodingErr $ AtKey e.tagKey MissingValue) (FO.lookup e.tagKey jObj)
|
55 | 55 | tag <- note (decodingErr $ AtKey e.tagKey $ TypeMismatch "String") (toString jTag)
|
56 |
| - when (tag /= name) $ |
57 |
| - Left $ decodingErr $ AtKey e.tagKey $ UnexpectedValue $ fromString tag |
58 |
| - pure {tag, decodingErr} |
59 |
| - |
60 |
| -withTagAndValues :: |
61 |
| - Encoding -> |
62 |
| - Json -> |
63 |
| - String -> |
64 |
| - Either JsonDecodeError |
65 |
| - { tag :: String |
66 |
| - , values :: Json |
67 |
| - , decodingErr :: JsonDecodeError -> JsonDecodeError |
68 |
| - } |
| 56 | + when (tag /= name) |
| 57 | + $ Left |
| 58 | + $ decodingErr |
| 59 | + $ AtKey e.tagKey |
| 60 | + $ UnexpectedValue |
| 61 | + $ fromString tag |
| 62 | + pure { tag, decodingErr } |
| 63 | + |
| 64 | +withTagAndValues |
| 65 | + :: Encoding |
| 66 | + -> Json |
| 67 | + -> String |
| 68 | + -> Either JsonDecodeError |
| 69 | + { tag :: String |
| 70 | + , values :: Json |
| 71 | + , decodingErr :: JsonDecodeError -> JsonDecodeError |
| 72 | + } |
69 | 73 | withTagAndValues e j name = do
|
70 |
| - {tag, decodingErr} <- withTag e j name |
| 74 | + { tag, decodingErr } <- withTag e j name |
71 | 75 | jObj <- note (decodingErr $ TypeMismatch "Object") (toObject j)
|
72 | 76 | values <- note (decodingErr $ AtKey e.valuesKey MissingValue) (FO.lookup e.valuesKey jObj)
|
73 |
| - pure {tag, values, decodingErr} |
74 |
| - |
75 |
| -construct :: |
76 |
| - forall e t s . |
77 |
| - DecodeRepArgs t => |
78 |
| - Encoding -> |
79 |
| - Array Json -> |
80 |
| - (JsonDecodeError -> e) -> |
81 |
| - Either e (Rep.Constructor s t) |
| 77 | + pure { tag, values, decodingErr } |
| 78 | + |
| 79 | +construct |
| 80 | + :: forall e t s |
| 81 | + . DecodeRepArgs t |
| 82 | + => Encoding |
| 83 | + -> Array Json |
| 84 | + -> (JsonDecodeError -> e) |
| 85 | + -> Either e (Rep.Constructor s t) |
82 | 86 | construct e valuesArray decodingErr = do
|
83 |
| - {init, rest} <- lmap decodingErr $ decodeRepArgs valuesArray |
84 |
| - when (rest /= []) $ |
85 |
| - Left $ decodingErr $ AtKey e.valuesKey $ UnexpectedValue (fromArray rest) |
| 87 | + { init, rest } <- lmap decodingErr $ decodeRepArgs valuesArray |
| 88 | + when (rest /= []) |
| 89 | + $ Left |
| 90 | + $ decodingErr |
| 91 | + $ AtKey e.valuesKey |
| 92 | + $ UnexpectedValue (fromArray rest) |
86 | 93 | pure $ Rep.Constructor init
|
87 | 94 |
|
88 | 95 | instance decodeRepConstructorNoArgs :: IsSymbol name => DecodeRep (Rep.Constructor name Rep.NoArguments) where
|
89 | 96 | decodeRepWith e j = do
|
90 | 97 | let name = reflectSymbol (Proxy :: Proxy name)
|
91 |
| - {decodingErr} <- withTag e j name |
| 98 | + { decodingErr } <- withTag e j name |
92 | 99 | construct e [] decodingErr
|
93 |
| -else |
94 |
| -instance decodeRepConstructorArg :: (IsSymbol name, DecodeJson a) => DecodeRep (Rep.Constructor name (Rep.Argument a)) where |
| 100 | +else instance decodeRepConstructorArg :: (IsSymbol name, DecodeJson a) => DecodeRep (Rep.Constructor name (Rep.Argument a)) where |
95 | 101 | decodeRepWith e j = do
|
96 | 102 | let name = reflectSymbol (Proxy :: Proxy name)
|
97 |
| - {values, decodingErr} <- withTagAndValues e j name |
98 |
| - if e.unwrapSingleArguments |
99 |
| - then construct e [values] decodingErr |
100 |
| - else do |
101 |
| - valuesArray <- note (decodingErr $ AtKey e.valuesKey $ TypeMismatch "Array") (toArray values) |
102 |
| - construct e valuesArray decodingErr |
103 |
| -else |
104 |
| -instance decodeRepConstructor :: (IsSymbol name, DecodeRepArgs a) => DecodeRep (Rep.Constructor name a) where |
| 103 | + { values, decodingErr } <- withTagAndValues e j name |
| 104 | + if e.unwrapSingleArguments then construct e [ values ] decodingErr |
| 105 | + else do |
| 106 | + valuesArray <- note (decodingErr $ AtKey e.valuesKey $ TypeMismatch "Array") (toArray values) |
| 107 | + construct e valuesArray decodingErr |
| 108 | +else instance decodeRepConstructor :: (IsSymbol name, DecodeRepArgs a) => DecodeRep (Rep.Constructor name a) where |
105 | 109 | decodeRepWith e j = do
|
106 | 110 | let name = reflectSymbol (Proxy :: Proxy name)
|
107 |
| - {values, decodingErr} <- withTagAndValues e j name |
| 111 | + { values, decodingErr } <- withTagAndValues e j name |
108 | 112 | valuesArray <- note (decodingErr $ AtKey e.valuesKey $ TypeMismatch "Array") (toArray values)
|
109 | 113 | construct e valuesArray decodingErr
|
110 | 114 |
|
111 | 115 | class DecodeRepArgs r where
|
112 |
| - decodeRepArgs :: Array Json -> Either JsonDecodeError {init :: r, rest :: Array Json} |
| 116 | + decodeRepArgs :: Array Json -> Either JsonDecodeError { init :: r, rest :: Array Json } |
113 | 117 |
|
114 | 118 | instance decodeRepArgsNoArguments :: DecodeRepArgs Rep.NoArguments where
|
115 |
| - decodeRepArgs js = Right {init: Rep.NoArguments, rest: js} |
| 119 | + decodeRepArgs js = Right { init: Rep.NoArguments, rest: js } |
116 | 120 |
|
117 | 121 | instance decodeRepArgsProduct :: (DecodeRepArgs a, DecodeRepArgs b) => DecodeRepArgs (Rep.Product a b) where
|
118 | 122 | decodeRepArgs js = do
|
119 |
| - {init: a, rest: js'} <- decodeRepArgs js |
120 |
| - {init: b, rest: js''} <- decodeRepArgs js' |
121 |
| - pure {init: Rep.Product a b, rest: js''} |
| 123 | + { init: a, rest: js' } <- decodeRepArgs js |
| 124 | + { init: b, rest: js'' } <- decodeRepArgs js' |
| 125 | + pure { init: Rep.Product a b, rest: js'' } |
122 | 126 |
|
123 | 127 | instance decodeRepArgsArgument :: (DecodeJson a) => DecodeRepArgs (Rep.Argument a) where
|
124 | 128 | decodeRepArgs js = do
|
125 |
| - {head, tail} <- note (TypeMismatch "NonEmptyArray") (uncons js) |
126 |
| - {init: _, rest: tail} <<< Rep.Argument <$> decodeJson head |
| 129 | + { head, tail } <- note (TypeMismatch "NonEmptyArray") (uncons js) |
| 130 | + { init: _, rest: tail } <<< Rep.Argument <$> decodeJson head |
127 | 131 |
|
128 | 132 | -- | Decode `Json` representation of a value which has a `Generic` type.
|
129 | 133 | genericDecodeJson :: forall a r. Rep.Generic a r => DecodeRep r => Json -> Either JsonDecodeError a
|
@@ -154,15 +158,16 @@ instance decodeLiteralConstructor :: (IsSymbol name) => DecodeLiteral (Rep.Const
|
154 | 158 | let name = reflectSymbol (Proxy :: Proxy name)
|
155 | 159 | let decodingErr = Named name
|
156 | 160 | tag <- note (decodingErr $ TypeMismatch "String") (toString j)
|
157 |
| - when (tag /= tagNameTransform name) $ |
158 |
| - Left $ decodingErr $ UnexpectedValue (fromString tag) |
| 161 | + when (tag /= tagNameTransform name) |
| 162 | + $ Left |
| 163 | + $ decodingErr |
| 164 | + $ UnexpectedValue (fromString tag) |
159 | 165 | pure $ Rep.Constructor (Rep.NoArguments)
|
160 | 166 |
|
161 |
| - |
162 | 167 | type FailMessage =
|
163 | 168 | Text "`decodeLiteralSum` can only be used with sum types, where all of the constructors are nullary. This is because a string literal cannot be encoded into a product type."
|
164 | 169 |
|
165 |
| -instance decodeLiteralConstructorCannotTakeProduct |
166 |
| - :: Fail FailMessage |
167 |
| - => DecodeLiteral (Rep.Product a b) where |
168 |
| - decodeLiteral _ _ = unsafeCrashWith "unreachable DecodeLiteral was reached." |
| 170 | +instance decodeLiteralConstructorCannotTakeProduct :: |
| 171 | + Fail FailMessage => |
| 172 | + DecodeLiteral (Rep.Product a b) where |
| 173 | + decodeLiteral _ _ = unsafeCrashWith "unreachable DecodeLiteral was reached." |
0 commit comments