0 | module Language.JSON.Data
4 | import Data.String.Extra
15 | | JArray (List JSON)
16 | | JObject (List (String, JSON))
22 | JNull == JNull = True
23 | JBoolean x == JBoolean y = x == y
24 | JNumber x == JNumber y = x == y
25 | JString x == JString y = x == y
26 | JArray xs == JArray ys = assert_total $
xs == ys
27 | JObject xs == JObject ys = assert_total $
on (==) (sortBy $
compare `on` fst) xs ys
31 | b16ToHexString : Bits16 -> String
50 | other => assert_total $
51 | b16ToHexString (n `shiftR` 4) ++
52 | b16ToHexString (n .&. 15)
55 | showChar : Char -> String
65 | c => if isControl c || c >= '\127'
66 | then let hex = b16ToHexString (cast $
ord c)
67 | in "\\u" ++ justifyRight 4 '0' hex
71 | showString : String -> String
72 | showString x = "\"" ++ concatMap showChar (unpack x) ++ "\""
77 | stringify : JSON -> String
78 | stringify JNull = "null"
79 | stringify (JBoolean x) = if x then "true" else "false"
80 | stringify (JNumber x) = show x
81 | stringify (JString x) = showString x
82 | stringify (JArray xs) = "[" ++ stringifyValues xs ++ "]"
84 | stringifyValues : List JSON -> String
85 | stringifyValues [] = ""
86 | stringifyValues (x :: xs) = stringify x
89 | else "," ++ stringifyValues xs
90 | stringify (JObject xs) = "{" ++ stringifyProps xs ++ "}"
92 | stringifyProp : (String, JSON) -> String
93 | stringifyProp (key, value) = showString key ++ ":" ++ stringify value
95 | stringifyProps : List (String, JSON) -> String
96 | stringifyProps [] = ""
97 | stringifyProps (x :: xs) = stringifyProp x
100 | else "," ++ stringifyProps xs
107 | [Idris] Show JSON where
108 | showPrec d JNull = "JNull"
109 | showPrec d (JBoolean x) = showCon d "JBoolean" $
showArg x
110 | showPrec d (JNumber x) = showCon d "JNumber" $
showArg x
111 | showPrec d (JString x) = showCon d "JString" $
showArg x
112 | showPrec d (JArray xs) = assert_total $
showCon d "JArray" $
showArg xs
113 | showPrec d (JObject xs) = assert_total $
showCon d "JObject" $
showArg xs
120 | format : {default 0 curr : Nat} -> (n : Nat) -> JSON -> String
121 | format {curr} n json = indent curr $
formatValue curr n json
123 | formatValue : (curr, n : Nat) -> JSON -> String
124 | formatValue _ _ (JArray []) = "[]"
125 | formatValue curr n (JArray xs@(_ :: _)) = "[\n" ++ formatValues xs
128 | formatValues : (xs : List JSON) -> {auto ok : NonEmpty xs} -> String
129 | formatValues (x :: xs) = format {curr=(curr + n)} n x
131 | _ :: _ => ",\n" ++ formatValues xs
133 | formatValue _ _ (JObject []) = "{}"
134 | formatValue curr n (JObject xs@(_ :: _)) = "{\n" ++ formatProps xs
137 | formatProp : (String, JSON) -> String
138 | formatProp (key, value) = indent (curr + n) (showString key ++ ": ")
139 | ++ formatValue (curr + n) n value
141 | formatProps : (xs : List (String, JSON)) -> {auto ok : NonEmpty xs} -> String
142 | formatProps (x :: xs) = formatProp x
144 | _ :: _ => ",\n" ++ formatProps xs
146 | formatValue _ _ x = stringify x
153 | Cast Bool JSON where
157 | Cast Double JSON where
161 | Cast String JSON where
165 | Cast a JSON => Cast (List a) JSON where
166 | cast xs = JArray $
map cast xs
169 | lookup : String -> JSON -> Maybe JSON
170 | lookup key (JObject xs) = lookup key xs
171 | lookup key json = Nothing
174 | update : (Maybe JSON -> Maybe JSON) -> String -> JSON -> JSON
175 | update f key (JObject xs) = JObject $
updateAttr f key xs
177 | updateAttr : (Maybe JSON -> Maybe JSON) -> String -> List (String, JSON) -> List (String, JSON)
178 | updateAttr f key [] = do
179 | let Just y = f Nothing
182 | updateAttr f key ((nm, x) :: xs) = if key == nm
184 | let Just y = f (Just x)
187 | else (nm, x) :: updateAttr f key xs
188 | update f key json = json
191 | traverseJSON : Monad m => (JSON -> m JSON) -> JSON -> m JSON
192 | traverseJSON f (JArray xs) = do
193 | xs <- assert_total $
traverse (traverseJSON f) xs
195 | traverseJSON f (JObject xs) = do
196 | xs <- traverse (assert_total $
bitraverse pure $
traverseJSON f) xs
198 | traverseJSON f json = f json
201 | traverseJSON_ : Monad m => (JSON -> m ()) -> JSON -> m ()
202 | traverseJSON_ f json = ignore $
traverseJSON (\x => f x *> pure x) json