@@ -15,8 +15,8 @@ module Data.Argonaut.Decode.Generic.Rep (
15
15
import Prelude
16
16
17
17
import Control.Alt ((<|>))
18
- import Data.Argonaut.Core (Json , toArray , toObject , toString )
19
- import Data.Argonaut.Decode.Class (class DecodeJson , decodeJson )
18
+ import Data.Argonaut.Core (Json , fromString , toArray , toObject , toString , fromArray )
19
+ import Data.Argonaut.Decode (class DecodeJson , decodeJson , JsonDecodeError (..) )
20
20
import Data.Argonaut.Types.Generic.Rep (Encoding , defaultEncoding )
21
21
import Data.Array (uncons )
22
22
import Data.Bifunctor (lmap )
@@ -28,13 +28,13 @@ import Partial.Unsafe (unsafeCrashWith)
28
28
import Prim.TypeError (class Fail , Text )
29
29
30
30
class DecodeRep r where
31
- decodeRepWith :: Encoding -> Json -> Either String r
31
+ decodeRepWith :: Encoding -> Json -> Either JsonDecodeError r
32
32
33
- decodeRep :: forall r . DecodeRep r => Json -> Either String r
33
+ decodeRep :: forall r . DecodeRep r => Json -> Either JsonDecodeError r
34
34
decodeRep = decodeRepWith defaultEncoding
35
35
36
36
instance decodeRepNoConstructors :: DecodeRep Rep.NoConstructors where
37
- decodeRepWith e _ = Left " Cannot decode empty data type"
37
+ decodeRepWith e _ = Left $ UnexpectedValue $ fromString " NoConstructors ( Cannot decode empty data type) "
38
38
39
39
instance decodeRepSum :: (DecodeRep a , DecodeRep b ) => DecodeRep (Rep.Sum a b ) where
40
40
decodeRepWith e j = Rep.Inl <$> decodeRepWith e j <|> Rep.Inr <$> decodeRepWith e j
@@ -43,45 +43,45 @@ withTag ::
43
43
Encoding ->
44
44
Json ->
45
45
String ->
46
- Either String
46
+ Either JsonDecodeError
47
47
{ tag :: String
48
- , decodingErr :: String -> String
48
+ , decodingErr :: JsonDecodeError -> JsonDecodeError
49
49
}
50
50
withTag e j name = do
51
- let decodingErr msg = " When decoding a " <> name <> " : " <> msg
52
- jObj <- note (decodingErr " expected an object " ) (toObject j)
53
- jTag <- note (decodingErr $ " ' " <> e.tagKey <> " ' property is missing " ) (FO .lookup e.tagKey jObj)
54
- tag <- note (decodingErr $ " ' " <> e.tagKey <> " ' property is not a string " ) (toString jTag)
51
+ let decodingErr = Named name
52
+ jObj <- note (decodingErr $ TypeMismatch " Object " ) (toObject j)
53
+ jTag <- note (decodingErr $ AtKey e.tagKey MissingValue ) (FO .lookup e.tagKey jObj)
54
+ tag <- note (decodingErr $ AtKey e.tagKey $ TypeMismatch " String " ) (toString jTag)
55
55
when (tag /= name) $
56
- Left $ decodingErr $ " ' " <> e.tagKey <> " ' property has an incorrect value "
56
+ Left $ decodingErr $ AtKey e.tagKey $ UnexpectedValue $ fromString tag
57
57
pure {tag, decodingErr}
58
58
59
59
withTagAndValues ::
60
60
Encoding ->
61
61
Json ->
62
62
String ->
63
- Either String
63
+ Either JsonDecodeError
64
64
{ tag :: String
65
65
, values :: Json
66
- , decodingErr :: String -> String
66
+ , decodingErr :: JsonDecodeError -> JsonDecodeError
67
67
}
68
68
withTagAndValues e j name = do
69
69
{tag, decodingErr} <- withTag e j name
70
- jObj <- note (decodingErr " expected an object " ) (toObject j)
71
- values <- note (decodingErr $ " ' " <> e.valuesKey <> " ' property is missing " ) (FO .lookup e.valuesKey jObj)
70
+ jObj <- note (decodingErr $ TypeMismatch " Object " ) (toObject j)
71
+ values <- note (decodingErr $ AtKey e.valuesKey MissingValue ) (FO .lookup e.valuesKey jObj)
72
72
pure {tag, values, decodingErr}
73
73
74
74
construct ::
75
75
forall e t s .
76
76
DecodeRepArgs t =>
77
77
Encoding ->
78
78
Array Json ->
79
- (String -> e ) ->
79
+ (JsonDecodeError -> e ) ->
80
80
Either e (Rep.Constructor s t )
81
81
construct e valuesArray decodingErr = do
82
82
{init, rest} <- lmap decodingErr $ decodeRepArgs valuesArray
83
83
when (rest /= [] ) $
84
- Left $ decodingErr $ " ' " <> e.valuesKey <> " ' property had too many values "
84
+ Left $ decodingErr $ AtKey e.valuesKey $ UnexpectedValue (fromArray rest)
85
85
pure $ Rep.Constructor init
86
86
87
87
instance decodeRepConstructorNoArgs :: IsSymbol name => DecodeRep (Rep.Constructor name Rep.NoArguments ) where
@@ -97,18 +97,18 @@ instance decodeRepConstructorArg :: (IsSymbol name, DecodeJson a) => DecodeRep (
97
97
if e.unwrapSingleArguments
98
98
then construct e [values] decodingErr
99
99
else do
100
- valuesArray <- note (decodingErr $ " ' " <> e.valuesKey <> " ' property is not an array " ) (toArray values)
100
+ valuesArray <- note (decodingErr $ AtKey e.valuesKey $ TypeMismatch " Array " ) (toArray values)
101
101
construct e valuesArray decodingErr
102
102
else
103
103
instance decodeRepConstructor :: (IsSymbol name , DecodeRepArgs a ) => DecodeRep (Rep.Constructor name a ) where
104
104
decodeRepWith e j = do
105
105
let name = reflectSymbol (SProxy :: SProxy name )
106
106
{tag, values, decodingErr} <- withTagAndValues e j name
107
- valuesArray <- note (decodingErr $ " ' " <> e.valuesKey <> " ' property is not an array " ) (toArray values)
107
+ valuesArray <- note (decodingErr $ AtKey e.valuesKey $ TypeMismatch " Array " ) (toArray values)
108
108
construct e valuesArray decodingErr
109
109
110
110
class DecodeRepArgs r where
111
- decodeRepArgs :: Array Json -> Either String { init :: r , rest :: Array Json }
111
+ decodeRepArgs :: Array Json -> Either JsonDecodeError { init :: r , rest :: Array Json }
112
112
113
113
instance decodeRepArgsNoArguments :: DecodeRepArgs Rep.NoArguments where
114
114
decodeRepArgs js = Right {init: Rep.NoArguments , rest: js}
@@ -121,40 +121,40 @@ instance decodeRepArgsProduct :: (DecodeRepArgs a, DecodeRepArgs b) => DecodeRep
121
121
122
122
instance decodeRepArgsArgument :: (DecodeJson a ) => DecodeRepArgs (Rep.Argument a ) where
123
123
decodeRepArgs js = do
124
- {head, tail} <- note " too few values were present " (uncons js)
124
+ {head, tail} <- note ( TypeMismatch " NonEmptyArray " ) (uncons js)
125
125
{init: _, rest: tail} <<< Rep.Argument <$> decodeJson head
126
126
127
127
-- | Decode `Json` representation of a value which has a `Generic` type.
128
- genericDecodeJson :: forall a r . Rep.Generic a r => DecodeRep r => Json -> Either String a
128
+ genericDecodeJson :: forall a r . Rep.Generic a r => DecodeRep r => Json -> Either JsonDecodeError a
129
129
genericDecodeJson = genericDecodeJsonWith defaultEncoding
130
130
131
131
-- | Decode `Json` representation of a value which has a `Generic` type.
132
132
-- | Takes a record for encoding settings.
133
- genericDecodeJsonWith :: forall a r . Rep.Generic a r => DecodeRep r => Encoding -> Json -> Either String a
133
+ genericDecodeJsonWith :: forall a r . Rep.Generic a r => DecodeRep r => Encoding -> Json -> Either JsonDecodeError a
134
134
genericDecodeJsonWith e = map Rep .to <<< decodeRepWith e
135
135
136
136
-- | A function for decoding `Generic` sum types using string literal representations.
137
- decodeLiteralSum :: forall a r . Rep.Generic a r => DecodeLiteral r => Json -> Either String a
137
+ decodeLiteralSum :: forall a r . Rep.Generic a r => DecodeLiteral r => Json -> Either JsonDecodeError a
138
138
decodeLiteralSum = decodeLiteralSumWithTransform identity
139
139
140
140
-- | A function for decoding `Generic` sum types using string literal representations.
141
141
-- | Takes a function for transforming the tag name in encoding.
142
- decodeLiteralSumWithTransform :: forall a r . Rep.Generic a r => DecodeLiteral r => (String -> String ) -> Json -> Either String a
142
+ decodeLiteralSumWithTransform :: forall a r . Rep.Generic a r => DecodeLiteral r => (String -> String ) -> Json -> Either JsonDecodeError a
143
143
decodeLiteralSumWithTransform tagNameTransform = map Rep .to <<< decodeLiteral tagNameTransform
144
144
145
145
class DecodeLiteral r where
146
- decodeLiteral :: (String -> String ) -> Json -> Either String r
146
+ decodeLiteral :: (String -> String ) -> Json -> Either JsonDecodeError r
147
147
148
148
instance decodeLiteralSumInst :: (DecodeLiteral a , DecodeLiteral b ) => DecodeLiteral (Rep.Sum a b ) where
149
149
decodeLiteral tagNameTransform j = Rep.Inl <$> decodeLiteral tagNameTransform j <|> Rep.Inr <$> decodeLiteral tagNameTransform j
150
150
151
151
instance decodeLiteralConstructor :: (IsSymbol name ) => DecodeLiteral (Rep.Constructor name (Rep.NoArguments )) where
152
152
decodeLiteral tagNameTransform j = do
153
153
let name = reflectSymbol (SProxy :: SProxy name )
154
- let decodingErr msg = " When decoding a " <> name <> " : " <> msg
155
- tag <- note (decodingErr " could not read string for constructor " ) (toString j)
154
+ let decodingErr = Named name
155
+ tag <- note (decodingErr $ TypeMismatch " String " ) (toString j)
156
156
when (tag /= tagNameTransform name) $
157
- Left $ decodingErr " string literal " <> tag <> " had an incorrect value. "
157
+ Left $ decodingErr $ UnexpectedValue (fromString tag)
158
158
pure $ Rep.Constructor (Rep.NoArguments )
159
159
160
160
0 commit comments