@@ -2,53 +2,72 @@ module Data.Argonaut.JCursor where
2
2
3
3
import Prelude
4
4
5
- import Data.Argonaut.Core
6
- import Data.Argonaut.Decode
7
- import Data.Argonaut.Encode
5
+ import Data.Argonaut.Core as J
6
+ import Data.Argonaut.Decode (class DecodeJson , decodeJson )
7
+ import Data.Argonaut.Encode (class EncodeJson , encodeJson )
8
+ import Data.Array as A
8
9
import Data.Either (Either (..))
10
+ import Data.Unfoldable (replicate )
9
11
import Data.Foldable (foldl )
10
- import Data.List (List (), zipWith , range , head , singleton , toList )
12
+ import Data.Int as I
13
+ import Data.List (List (), zipWith , range , head , singleton , fromFoldable )
11
14
import Data.Maybe (Maybe (..), fromMaybe , maybe )
12
- import Data.Monoid (Monoid )
15
+ import Data.Monoid (class Monoid )
16
+ import Data.StrMap as M
13
17
import Data.Tuple (Tuple (..), fst , snd )
14
18
15
- import qualified Data.Array as A
16
- import qualified Data.Int as I
17
- import qualified Data.Maybe.Unsafe as MU
18
- import qualified Data.StrMap as M
19
-
20
19
data JCursor
21
20
= JCursorTop
22
21
| JField String JCursor
23
22
| JIndex Int JCursor
24
23
25
- newtype JsonPrim
26
- = JsonPrim (forall a .
27
- (JNull -> a ) ->
28
- (JBoolean -> a ) ->
29
- (JNumber -> a ) ->
30
- (JString -> a ) ->
31
- a )
24
+ derive instance eqJCursor :: Eq JCursor
25
+ derive instance ordJCursor :: Ord JCursor
26
+
27
+ instance showJCursor :: Show JCursor where
28
+ show JCursorTop = " "
29
+ show (JField i c) = " ." <> i <> show c
30
+ show (JIndex i c) = " [" <> show i <> " ]" <> show c
31
+
32
+ instance semigroupJCursor :: Semigroup JCursor where
33
+ append a JCursorTop = a
34
+ append JCursorTop b = b
35
+ append (JField i a) b = JField i (a <> b)
36
+ append (JIndex i a) b = JIndex i (a <> b)
37
+
38
+ instance monoidJCursor :: Monoid JCursor where
39
+ mempty = JCursorTop
40
+
41
+ instance encodeJsonJCursor :: EncodeJson JCursor where
42
+ encodeJson = encodeJson <<< loop where
43
+ loop JCursorTop = []
44
+ loop (JField i c) = [encodeJson i] <> loop c
45
+ loop (JIndex i c) = [encodeJson i] <> loop c
46
+
47
+ newtype JsonPrim = JsonPrim (forall a . (J.JNull -> a ) -> (J.JBoolean -> a ) -> (J.JNumber -> a ) -> (J.JString -> a ) -> a )
32
48
33
- runJsonPrim :: JsonPrim -> (forall a . (JNull -> a ) -> (JBoolean -> a ) -> (JNumber -> a ) -> (JString -> a ) -> a )
49
+ runJsonPrim :: JsonPrim -> (forall a . (J. JNull -> a ) -> (J. JBoolean -> a ) -> (J. JNumber -> a ) -> (J. JString -> a ) -> a )
34
50
runJsonPrim (JsonPrim p) = p
35
51
36
- foreign import exactNull :: JNull
52
+ instance showJsonPrim :: Show JsonPrim where
53
+ show p = runJsonPrim p show show show show
54
+
55
+ foreign import exactNull :: J.JNull
37
56
38
57
primNull :: JsonPrim
39
58
primNull = JsonPrim (\f _ _ _ -> f exactNull)
40
59
41
- primBool :: JBoolean -> JsonPrim
60
+ primBool :: J. JBoolean -> JsonPrim
42
61
primBool v = JsonPrim (\_ f _ _ -> f v)
43
62
44
- primNum :: JNumber -> JsonPrim
63
+ primNum :: J. JNumber -> JsonPrim
45
64
primNum v = JsonPrim (\_ _ f _ -> f v)
46
65
47
- primStr :: JString -> JsonPrim
66
+ primStr :: J. JString -> JsonPrim
48
67
primStr v = JsonPrim (\_ _ _ f -> f v)
49
68
50
- primToJson :: JsonPrim -> Json
51
- primToJson p = runJsonPrim p fromNull fromBoolean fromNumber fromString
69
+ primToJson :: JsonPrim -> J. Json
70
+ primToJson p = runJsonPrim p J . fromNull J . fromBoolean J . fromNumber J . fromString
52
71
53
72
insideOut :: JCursor -> JCursor
54
73
insideOut JCursorTop = JCursorTop
@@ -67,157 +86,91 @@ downIndex i = downIndex' where
67
86
downIndex' (JField i' c) = JField i' (downIndex' c)
68
87
downIndex' (JIndex i' c) = JIndex i' (downIndex' c)
69
88
70
- cursorGet :: JCursor -> Json -> Maybe Json
89
+ cursorGet :: JCursor -> J. Json -> Maybe J. Json
71
90
cursorGet JCursorTop = Just
72
- cursorGet (JField i c) = foldJsonObject Nothing g where
73
- g m = M .lookup i m >>= cursorGet c
74
- cursorGet (JIndex i c) = foldJsonArray Nothing g where
75
- g a = a A .!! i >>= cursorGet c
91
+ cursorGet (JField i c) = J .foldJsonObject Nothing (cursorGet c <=< M .lookup i)
92
+ cursorGet (JIndex i c) = J .foldJsonArray Nothing (cursorGet c <=< (_ A .!! i))
76
93
77
- inferEmpty :: JCursor -> Json
78
- inferEmpty JCursorTop = jsonNull
79
- inferEmpty (JField _ _) = jsonEmptyObject
80
- inferEmpty (JIndex _ _) = jsonEmptyArray
94
+ inferEmpty :: JCursor -> J. Json
95
+ inferEmpty JCursorTop = J . jsonNull
96
+ inferEmpty (JField _ _) = J . jsonEmptyObject
97
+ inferEmpty (JIndex _ _) = J . jsonEmptyArray
81
98
82
- cursorSet :: JCursor -> Json -> Json -> Maybe Json
99
+ cursorSet :: JCursor -> J. Json -> J. Json -> Maybe J. Json
83
100
cursorSet JCursorTop v = pure <<< const v
84
- cursorSet (JField i c) v = foldJsonObject defaultObj mergeObjs
101
+ cursorSet (JField i c) v = J . foldJsonObject defaultObj mergeObjs
85
102
where
86
- defaultObj :: Maybe Json
87
- defaultObj = fromObject <<< M .singleton i <$> cursorSet c v (inferEmpty c)
88
-
89
- mergeObjs :: JObject -> Maybe Json
90
- mergeObjs m =
91
- fromObject <<< flip (M .insert i) m <$>
92
- ( cursorSet c v $ fromMaybe (inferEmpty c) (M .lookup i m))
93
- cursorSet (JIndex i c) v = foldJsonArray defaultArr mergeArrs
103
+ defaultObj :: Maybe J. Json
104
+ defaultObj = J . fromObject <<< M .singleton i <$> cursorSet c v (inferEmpty c)
105
+ mergeObjs :: J.JObject -> Maybe J.Json
106
+ mergeObjs m
107
+ = J .fromObject
108
+ <<< flip (M .insert i) m
109
+ <$> cursorSet c v ( fromMaybe (inferEmpty c) (M .lookup i m))
110
+ cursorSet (JIndex i c) v = J . foldJsonArray defaultArr mergeArrs
94
111
where
95
- defaultArr :: Maybe Json
96
- defaultArr = fromArray <<< MU .fromJust <<<
97
- flip (A .updateAt i) (A .replicate (i + 1 ) jsonNull) <$>
98
- cursorSet c v (inferEmpty c)
99
-
100
- mergeArrs :: JArray -> Maybe Json
101
- mergeArrs a = (cursorSet c v $ fromMaybe (inferEmpty c) (a A .!! i)) >>= setArr a i
102
-
103
- setArr :: JArray -> Int -> Json -> Maybe Json
112
+ defaultArr :: Maybe J.Json
113
+ defaultArr
114
+ = J .fromArray
115
+ <$> (flip (A .updateAt i) (replicate (i + 1 ) J .jsonNull) =<< cursorSet c v (inferEmpty c))
116
+ mergeArrs :: J.JArray -> Maybe J.Json
117
+ mergeArrs a =
118
+ setArr a i =<< cursorSet c v (fromMaybe (inferEmpty c) (a A .!! i))
119
+ setArr :: J.JArray -> Int -> J.Json -> Maybe J.Json
104
120
setArr xs i v =
105
121
let len = A .length xs
106
122
in if i < 0
107
123
then Nothing
108
124
else if i >= len
109
- then setArr (xs <> (A .replicate (i - len + 1 ) jsonNull)) i v
110
- else Just <<< fromArray <<< MU .fromJust $ A .updateAt i v xs
111
-
125
+ then setArr (xs <> (replicate (i - len + 1 ) J .jsonNull)) i v
126
+ else J .fromArray <$> A .updateAt i v xs
112
127
113
- toPrims :: Json -> List (Tuple JCursor JsonPrim )
114
- toPrims = foldJson nullFn boolFn numFn strFn arrFn objFn
128
+ toPrims :: J. Json -> List (Tuple JCursor JsonPrim )
129
+ toPrims = J . foldJson nullFn boolFn numFn strFn arrFn objFn
115
130
where
116
131
mkTop :: JsonPrim -> List (Tuple JCursor JsonPrim )
117
132
mkTop p = singleton $ Tuple JCursorTop p
118
-
119
- nullFn :: JNull -> List (Tuple JCursor JsonPrim )
133
+ nullFn :: J.JNull -> List (Tuple JCursor JsonPrim )
120
134
nullFn _ = mkTop primNull
121
-
122
- boolFn :: JBoolean -> List (Tuple JCursor JsonPrim )
135
+ boolFn :: J.JBoolean -> List (Tuple JCursor JsonPrim )
123
136
boolFn b = mkTop $ primBool b
124
-
125
- numFn :: JNumber -> List (Tuple JCursor JsonPrim )
137
+ numFn :: J.JNumber -> List (Tuple JCursor JsonPrim )
126
138
numFn n = mkTop $ primNum n
127
-
128
- strFn :: JString -> List (Tuple JCursor JsonPrim )
139
+ strFn :: J.JString -> List (Tuple JCursor JsonPrim )
129
140
strFn s = mkTop $ primStr s
130
-
131
- arrFn :: JArray -> List (Tuple JCursor JsonPrim )
141
+ arrFn :: J.JArray -> List (Tuple JCursor JsonPrim )
132
142
arrFn arr =
133
- let zipped :: List (Tuple Int Json )
134
- zipped = zipWith Tuple (range 0 (A .length arr - 1 )) (toList arr)
135
-
143
+ let zipped :: List (Tuple Int J.Json )
144
+ zipped = zipWith Tuple (range 0 (A .length arr - 1 )) (fromFoldable arr)
136
145
in zipped >>= arrFn'
137
-
138
- arrFn' :: Tuple Int Json -> List (Tuple JCursor JsonPrim )
139
- arrFn' (Tuple i j) = toList ((\t -> Tuple (JIndex i (fst t)) (snd t))
140
- <$> toPrims j)
141
-
142
-
143
- objFn :: JObject -> List (Tuple JCursor JsonPrim )
146
+ arrFn' :: Tuple Int J.Json -> List (Tuple JCursor JsonPrim )
147
+ arrFn' (Tuple i j) =
148
+ fromFoldable ((\t -> Tuple (JIndex i (fst t)) (snd t)) <$> toPrims j)
149
+ objFn :: J.JObject -> List (Tuple JCursor JsonPrim )
144
150
objFn obj =
145
- let f :: Tuple String Json -> List (Tuple JCursor JsonPrim )
146
- f (Tuple i j) = ((\t -> Tuple (JField i (fst t)) (snd t))
147
- <$> toPrims j)
151
+ let f :: Tuple String J.Json -> List (Tuple JCursor JsonPrim )
152
+ f (Tuple i j) = (\t -> Tuple (JField i (fst t)) (snd t)) <$> toPrims j
148
153
in M .toList obj >>= f
149
154
150
-
151
- fromPrims :: List (Tuple JCursor JsonPrim ) -> Maybe Json
155
+ fromPrims :: List (Tuple JCursor JsonPrim ) -> Maybe J.Json
152
156
fromPrims lst = foldl f (inferEmpty <<< fst <$> head lst) lst
153
157
where
154
- f :: Maybe Json -> Tuple JCursor JsonPrim -> Maybe Json
158
+ f :: Maybe J. Json -> Tuple JCursor JsonPrim -> Maybe J. Json
155
159
f j (Tuple c p) = j >>= cursorSet c (primToJson p)
156
160
157
- instance showJCursor :: Show JCursor where
158
- show JCursorTop = " "
159
- show (JField i c) = " ." <> i <> show c
160
- show (JIndex i c) = " [" <> show i <> " ]" <> show c
161
-
162
- instance showJsonPrim :: Show JsonPrim where
163
- show p = runJsonPrim p show show show show
164
-
165
- instance eqJCursor :: Eq JCursor where
166
- eq JCursorTop JCursorTop = true
167
- eq (JField i1 c1) (JField i2 c2) = i1 == i2 && c1 == c2
168
- eq (JIndex i1 c1) (JIndex i2 c2) = i1 == i2 && c1 == c2
169
- eq _ _ = false
170
-
171
- instance ordJCursor :: Ord JCursor where
172
- compare JCursorTop JCursorTop = EQ
173
- compare JCursorTop _ = LT
174
- compare _ JCursorTop = GT
175
- compare (JField _ _) (JIndex _ _) = LT
176
- compare (JIndex _ _) (JField _ _) = GT
177
- compare (JField i1 c1) (JField i2 c2) = case compare i1 i2 of
178
- EQ -> compare c1 c2
179
- x -> x
180
- compare (JIndex i1 c1) (JIndex i2 c2) = case compare i1 i2 of
181
- EQ -> compare c1 c2
182
- x -> x
183
-
184
- instance semigroupJCursor :: Semigroup JCursor where
185
- append a JCursorTop = a
186
- append JCursorTop b = b
187
- append (JField i a) b = JField i (a <> b)
188
- append (JIndex i a) b = JIndex i (a <> b)
189
-
190
- instance monoidJCursor :: Monoid JCursor where
191
- mempty = JCursorTop
192
-
193
- instance encodeJsonJCursor :: EncodeJson JCursor where
194
- encodeJson = encodeJson <<< loop where
195
- loop JCursorTop = []
196
- loop (JField i c) = [encodeJson i] <> loop c
197
- loop (JIndex i c) = [encodeJson i] <> loop c
198
-
199
- fail :: forall a b . (Show a ) => a -> Either String b
200
- fail x = Left $ " Expected String or Number but found: " ++ show x
161
+ fail :: forall a b . Show a => a -> Either String b
162
+ fail x = Left $ " Expected String or Number but found: " <> show x
201
163
202
164
instance decodeJsonJCursor :: DecodeJson JCursor where
203
165
decodeJson j = decodeJson j >>= loop
204
166
where
205
- loop :: Array Json -> Either String JCursor
167
+ loop :: Array J. Json -> Either String JCursor
206
168
loop arr =
207
- maybe (Right JCursorTop ) goLoop do
208
- x <- A .head arr
209
- xs <- A .tail arr
210
- pure $ Tuple x xs
211
-
212
- goLoop :: Tuple Json (Array Json ) -> Either String JCursor
169
+ maybe (Right JCursorTop ) goLoop $ Tuple <$> A .head arr <*> A .tail arr
170
+ goLoop :: Tuple J.Json (Array J.Json ) -> Either String JCursor
213
171
goLoop (Tuple x xs) = do
214
172
c <- loop xs
215
- foldJson fail fail (goNum c) (Right <<< (flip JField c)) fail fail x
216
-
217
- goNum :: JCursor -> JNumber -> Either String JCursor
218
- goNum c num =
219
- maybe (Left " Not an Int" ) (Right <<< (flip JIndex c)) $ I .fromNumber num
220
-
221
-
222
-
223
-
173
+ J .foldJson fail fail (goNum c) (Right <<< flip JField c) fail fail x
174
+ goNum :: JCursor -> J.JNumber -> Either String JCursor
175
+ goNum c =
176
+ maybe (Left " Not an Int" ) (Right <<< flip JIndex c) <<< I .fromNumber
0 commit comments