1
1
module Data.Argonaut.Decode.Combinators
2
2
( getField
3
+ , getFieldDeprecated
3
4
, getFieldOptional
5
+ , getFieldOptionalDeprecated
6
+ , getFieldOptional'
4
7
, defaultField
8
+ , defaultFieldDeprecated
9
+ , (.:)
5
10
, (.?)
11
+ , (.:!)
12
+ , (.:?)
6
13
, (.??)
14
+ , (.!=)
7
15
, (.?=)
8
16
) where
9
17
10
18
import Prelude
11
19
12
- import Data.Argonaut.Core (Json )
20
+ import Data.Argonaut.Core (Json , isNull )
13
21
import Data.Argonaut.Decode.Class (class DecodeJson , decodeJson )
14
22
import Data.Bifunctor (lmap )
15
23
import Data.Either (Either (..))
16
24
import Data.Maybe (Maybe (..), fromMaybe , maybe )
17
25
import Foreign.Object as FO
26
+ import Prim.TypeError (class Warn , Text )
18
27
28
+ -- | Attempt to get the value for a given key on an `Object Json`.
29
+ -- |
30
+ -- | Use this accessor if the key and value *must* be present in your object.
31
+ -- | If the key and value are optional, use `getFieldOptional'` (`.:?`) instead.
19
32
getField :: forall a . DecodeJson a => FO.Object Json -> String -> Either String a
20
33
getField o s =
21
34
maybe
22
35
(Left $ " Expected field " <> show s)
23
36
(elaborateFailure s <<< decodeJson)
24
37
(FO .lookup s o)
25
38
26
- infix 7 getField as .?
39
+ infix 7 getField as .:
27
40
41
+ getFieldDeprecated
42
+ :: forall a . Warn ( Text " `.?` is deprecated, use `.:` instead" )
43
+ => DecodeJson a
44
+ => FO.Object Json
45
+ -> String
46
+ -> Either String a
47
+ getFieldDeprecated = getField
48
+
49
+ infix 7 getFieldDeprecated as .?
50
+
51
+ -- | Attempt to get the value for a given key on an `Object Json`.
52
+ -- |
53
+ -- | The result will be `Right Nothing` if the key and value are not present,
54
+ -- | or if the key is present and the value is `null`.
55
+ -- |
56
+ -- | Use this accessor if the key and value are optional in your object.
57
+ -- | If the key and value are mandatory, use `getField` (`.:`) instead.
58
+ getFieldOptional' :: forall a . DecodeJson a => FO.Object Json -> String -> Either String (Maybe a )
59
+ getFieldOptional' o s =
60
+ maybe
61
+ (pure Nothing )
62
+ decode
63
+ (FO .lookup s o)
64
+ where
65
+ decode json =
66
+ if isNull json
67
+ then pure Nothing
68
+ else Just <$> decodeJson json
69
+
70
+ infix 7 getFieldOptional' as .:?
71
+
72
+ -- | Attempt to get the value for a given key on an `Object Json`.
73
+ -- |
74
+ -- | The result will be `Right Nothing` if the key and value are not present,
75
+ -- | but will fail if the key is present but the value cannot be converted to the right type.
76
+ -- |
77
+ -- | This function will treat `null` as a value and attempt to decode it into your desired type.
78
+ -- | If you would like to treat `null` values the same as absent values, use
79
+ -- | `getFieldOptional` (`.:?`) instead.
28
80
getFieldOptional :: forall a . DecodeJson a => FO.Object Json -> String -> Either String (Maybe a )
29
81
getFieldOptional o s =
30
82
maybe
@@ -34,12 +86,48 @@ getFieldOptional o s =
34
86
where
35
87
decode json = Just <$> (elaborateFailure s <<< decodeJson) json
36
88
37
- infix 7 getFieldOptional as .??
89
+ infix 7 getFieldOptional as .:!
90
+
91
+ getFieldOptionalDeprecated
92
+ :: forall a . Warn ( Text " `.??` is deprecated, use `.:!` or `.:?` instead" )
93
+ => DecodeJson a
94
+ => FO.Object Json
95
+ -> String
96
+ -> Either String (Maybe a )
97
+ getFieldOptionalDeprecated = getFieldOptional
38
98
99
+ infix 7 getFieldOptionalDeprecated as .??
100
+
101
+ -- | Helper for use in combination with `.:?` to provide default values for optional
102
+ -- | `Object Json` fields.
103
+ -- |
104
+ -- | Example usage:
105
+ -- | ```purescript
106
+ -- | newtype MyType = MyType
107
+ -- | { foo :: String
108
+ -- | , bar :: Maybe Int
109
+ -- | , baz :: Boolean
110
+ -- | }
111
+ -- |
112
+ -- | instance decodeJsonMyType :: DecodeJson MyType where
113
+ -- | decodeJson json = do
114
+ -- | x <- decodeJson json
115
+ -- | foo <- x .: "foo" -- mandatory field
116
+ -- | bar <- x .:? "bar" -- optional field
117
+ -- | baz <- x .:? "baz" .!= false -- optional field with default value of `false`
118
+ -- | pure $ MyType { foo, bar, baz }
119
+ -- | ```
39
120
defaultField :: forall a . Either String (Maybe a ) -> a -> Either String a
40
121
defaultField parser default = fromMaybe default <$> parser
41
122
42
- infix 6 defaultField as .?=
123
+ infix 6 defaultField as .!=
124
+
125
+ defaultFieldDeprecated
126
+ :: forall a . Warn ( Text " `.?=` is deprecated, use `.!=` instead" )
127
+ => Either String (Maybe a ) -> a -> Either String a
128
+ defaultFieldDeprecated = defaultField
129
+
130
+ infix 6 defaultFieldDeprecated as .?=
43
131
44
132
elaborateFailure :: ∀ a . String -> Either String a -> Either String a
45
133
elaborateFailure s e =
0 commit comments