on master help sign in
Stop relying on aeson, parse JSON with my parser
00a3069Evan Czaplicki
elm-compiler.cabal+1−1
@@ -91,6 +91,7 @@ Library
91 Generate.JavaScript.Builder,
91 Generate.JavaScript.Builder,
92 Generate.JavaScript.Expression,
92 Generate.JavaScript.Expression,
93 Generate.JavaScript.Name,
93 Generate.JavaScript.Name,
94+ Json.Decode.Internals,
94 Nitpick.PatternMatches,
95 Nitpick.PatternMatches,
95 Nitpick.TopLevelTypes,
96 Nitpick.TopLevelTypes,
96 Optimize.Case,
97 Optimize.Case,
@@ -146,7 +147,6 @@ Library
146 Paths_elm_compiler
147 Paths_elm_compiler
147
148
148 Build-depends:
149 Build-depends:
149− aeson >= 0.11,
150 ansi-terminal >= 0.7 && < 0.8,
150 ansi-terminal >= 0.7 && < 0.8,
151 ansi-wl-pprint >= 0.6.7 && < 0.7,
151 ansi-wl-pprint >= 0.6.7 && < 0.7,
152 base >=4.8 && <5,
152 base >=4.8 && <5,
src/Elm/Compiler/Module.hs+6−2
@@ -14,6 +14,7 @@ module Elm.Compiler.Module
14 , dehyphenate
14 , dehyphenate
15 , encode
15 , encode
16 , decoder
16 , decoder
17+ , Error(..)
17
18
18 -- canonical names
19 -- canonical names
19 , ModuleName.Canonical(..)
20 , ModuleName.Canonical(..)
@@ -98,12 +99,15 @@ encode =
98 Encode.text
99 Encode.text
99
100
100
101
102+data Error = BadModuleName
103+
104+
101−decoder :: Decode.Decoder Raw
105+decoder :: Decode.Decoder Error Raw
102decoder =
106decoder =
103 do txt <- Decode.text
107 do txt <- Decode.text
104 case nameFromText txt of
108 case nameFromText txt of
105 Nothing ->
109 Nothing ->
106− Decode.fail "Expecting a module name like \"Html.Events\""
110+ Decode.fail BadModuleName
107
111
108 Just name ->
112 Just name ->
109 Decode.succeed name
113 Decode.succeed name
src/Elm/Compiler/Type.hs+6−2
@@ -8,6 +8,7 @@ module Elm.Compiler.Type
8 , Alias(..)
8 , Alias(..)
9 , Union(..)
9 , Union(..)
10 , encode
10 , encode
11+ , Error(..)
11 , decoder
12 , decoder
12 , encodeMetadata
13 , encodeMetadata
13 )
14 )
@@ -187,12 +188,15 @@ encode tipe =
187 Encode.text (Text.pack (toString OneLine tipe))
188 Encode.text (Text.pack (toString OneLine tipe))
188
189
189
190
191+data Error = BadType
192+
193+
190−decoder :: Decode.Decoder Type
194+decoder :: Decode.Decoder Error Type
191decoder =
195decoder =
192 do txt <- Decode.text
196 do txt <- Decode.text
193 case Parse.run Type.expression (Text.encodeUtf8 (Text.replace "'" "_" txt)) of
197 case Parse.run Type.expression (Text.encodeUtf8 (Text.replace "'" "_" txt)) of
194 Left _ ->
198 Left _ ->
195− Decode.fail "Expecting a type, like (String -> Int)"
199+ Decode.fail BadType
196
200
197 Right (tipe, _, _) ->
201 Right (tipe, _, _) ->
198 Decode.succeed (fromRawType tipe)
202 Decode.succeed (fromRawType tipe)
src/Elm/Docs.hs+79−74
@@ -33,8 +33,8 @@ import qualified Elm.Compiler.Module as Module
33import qualified Elm.Compiler.Type as Type
33import qualified Elm.Compiler.Type as Type
34import qualified Elm.Compiler.Type.Extract as Extract
34import qualified Elm.Compiler.Type.Extract as Extract
35import qualified Elm.Name as N
35import qualified Elm.Name as N
36−import qualified Json.Decode as Decode
36+import qualified Json.Decode as D
37−import qualified Json.Encode as Encode
37+import qualified Json.Encode as E
38import Json.Encode ((==>))
38import Json.Encode ((==>))
39import qualified Reporting.Annotation as A
39import qualified Reporting.Annotation as A
40import qualified Reporting.Error as Error
40import qualified Reporting.Error as Error
@@ -95,175 +95,180 @@ data Binop = Binop Comment Type.Type Binop.Associativity Binop.Precedence
95-- JSON ENCODE / DECODE
95-- JSON ENCODE / DECODE
96
96
97
97
98−encode :: Module -> Encode.Value
98+encode :: Module -> E.Value
99encode (Module name comment unions aliases values binops) =
99encode (Module name comment unions aliases values binops) =
100− Encode.object $
100+ E.object $
101 [ "name" ==> Module.encode name
101 [ "name" ==> Module.encode name
102− , "comment" ==> Encode.text comment
102+ , "comment" ==> E.text comment
103− , "unions" ==> Encode.list encodeUnion (Map.toList unions)
103+ , "unions" ==> E.list encodeUnion (Map.toList unions)
104− , "aliases" ==> Encode.list encodeAlias (Map.toList aliases)
104+ , "aliases" ==> E.list encodeAlias (Map.toList aliases)
105− , "values" ==> Encode.list encodeValue (Map.toList values)
105+ , "values" ==> E.list encodeValue (Map.toList values)
106− , "binops" ==> Encode.list encodeBinop (Map.toList binops)
106+ , "binops" ==> E.list encodeBinop (Map.toList binops)
107 ]
107 ]
108
108
109
109
110−decoder :: Decode.Decoder Module
110+decoder :: D.Decoder Error Module
111decoder =
111decoder =
112 Module
112 Module
113− <$> Decode.field "name" Module.decoder
113+ <$> D.field "name" Module.decoder
114− <*> Decode.field "comment" Decode.text
114+ <*> D.field "comment" D.text
115− <*> Decode.field "unions" (dictDecoder union)
115+ <*> D.field "unions" (dictDecoder union)
116− <*> Decode.field "aliases" (dictDecoder alias)
116+ <*> D.field "aliases" (dictDecoder alias)
117− <*> Decode.field "values" (dictDecoder value)
117+ <*> D.field "values" (dictDecoder value)
118− <*> Decode.field "binops" (dictDecoder binop)
118+ <*> D.field "binops" (dictDecoder binop)
119
119
120
120
121−dictDecoder :: Decode.Decoder a -> Decode.Decoder (Map.Map N.Name a)
121+dictDecoder :: D.Decoder Error a -> D.Decoder Error (Map.Map N.Name a)
122dictDecoder entryDecoder =
122dictDecoder entryDecoder =
123− Map.fromList <$> Decode.list (named entryDecoder)
123+ Map.fromList <$> D.list (named entryDecoder)
124
124
125
125
126−named :: Decode.Decoder a -> Decode.Decoder (N.Name, a)
126+named :: D.Decoder Error a -> D.Decoder Error (N.Name, a)
127named entryDecoder =
127named entryDecoder =
128 (,)
128 (,)
129− <$> Decode.field "name" Decode.text
129+ <$> D.field "name" D.text
130 <*> entryDecoder
130 <*> entryDecoder
131
131
132
132
133+data Error
134+ = BadAssociativity
135+ | BadType
136+
137+
133
138
134-- UNION JSON
139-- UNION JSON
135
140
136
141
137−encodeUnion :: (N.Name, Union) -> Encode.Value
142+encodeUnion :: (N.Name, Union) -> E.Value
138encodeUnion (name, Union comment args cases) =
143encodeUnion (name, Union comment args cases) =
139− Encode.object
144+ E.object
140− [ "name" ==> Encode.text name
145+ [ "name" ==> E.text name
141− , "comment" ==> Encode.text comment
146+ , "comment" ==> E.text comment
142− , "args" ==> Encode.list Encode.text args
147+ , "args" ==> E.list E.text args
143− , "cases" ==> Encode.list encodeCase cases
148+ , "cases" ==> E.list encodeCase cases
144 ]
149 ]
145
150
146
151
147−union :: Decode.Decoder Union
152+union :: D.Decoder Error Union
148union =
153union =
149 Union
154 Union
150− <$> Decode.field "comment" Decode.text
155+ <$> D.field "comment" D.text
151− <*> Decode.field "args" (Decode.list Decode.text)
156+ <*> D.field "args" (D.list D.text)
152− <*> Decode.field "cases" (Decode.list caseDecoder)
157+ <*> D.field "cases" (D.list caseDecoder)
153
158
154
159
155−encodeCase :: ( N.Name, [Type.Type] ) -> Encode.Value
160+encodeCase :: ( N.Name, [Type.Type] ) -> E.Value
156encodeCase ( tag, args ) =
161encodeCase ( tag, args ) =
157− Encode.list id [ Encode.text tag, Encode.list Type.encode args ]
162+ E.list id [ E.text tag, E.list Type.encode args ]
158
163
159
164
160−caseDecoder :: Decode.Decoder ( N.Name, [Type.Type] )
165+caseDecoder :: D.Decoder Error ( N.Name, [Type.Type] )
161caseDecoder =
166caseDecoder =
162 (,)
167 (,)
163− <$> Decode.index 0 Decode.text
168+ <$> D.index 0 D.text
164− <*> Decode.index 1 (Decode.list Type.decoder)
169+ <*> D.index 1 (D.list typeDecoder)
165
170
166
171
167
172
168-- ALIAS JSON
173-- ALIAS JSON
169
174
170
175
171−encodeAlias :: (N.Name, Alias) -> Encode.Value
176+encodeAlias :: (N.Name, Alias) -> E.Value
172encodeAlias ( name, Alias comment args tipe) =
177encodeAlias ( name, Alias comment args tipe) =
173− Encode.object
178+ E.object
174− [ "name" ==> Encode.text name
179+ [ "name" ==> E.text name
175− , "comment" ==> Encode.text comment
180+ , "comment" ==> E.text comment
176− , "args" ==> Encode.list Encode.text args
181+ , "args" ==> E.list E.text args
177 , "type" ==> Type.encode tipe
182 , "type" ==> Type.encode tipe
178 ]
183 ]
179
184
180
185
181−alias :: Decode.Decoder Alias
186+alias :: D.Decoder Error Alias
182alias =
187alias =
183 Alias
188 Alias
184− <$> Decode.field "comment" Decode.text
189+ <$> D.field "comment" D.text
185− <*> Decode.field "args" (Decode.list Decode.text)
190+ <*> D.field "args" (D.list D.text)
186− <*> Decode.field "type" Type.decoder
191+ <*> D.field "type" typeDecoder
187
192
188
193
189
194
190-- VALUE JSON
195-- VALUE JSON
191
196
192
197
193−encodeValue :: (N.Name, Value) -> Encode.Value
198+encodeValue :: (N.Name, Value) -> E.Value
194encodeValue (name, Value comment tipe) =
199encodeValue (name, Value comment tipe) =
195− Encode.object
200+ E.object
196− [ "name" ==> Encode.text name
201+ [ "name" ==> E.text name
197− , "comment" ==> Encode.text comment
202+ , "comment" ==> E.text comment
198 , "type" ==> Type.encode tipe
203 , "type" ==> Type.encode tipe
199 ]
204 ]
200
205
201
206
202−value :: Decode.Decoder Value
207+value :: D.Decoder Error Value
203value =
208value =
204 Value
209 Value
205− <$> Decode.field "comment" Decode.text
210+ <$> D.field "comment" D.text
206− <*> Decode.field "type" Type.decoder
211+ <*> D.field "type" typeDecoder
207
212
208
213
209
214
210-- BINOP JSON
215-- BINOP JSON
211
216
212
217
213−encodeBinop :: (N.Name, Binop) -> Encode.Value
218+encodeBinop :: (N.Name, Binop) -> E.Value
214encodeBinop (name, Binop comment tipe assoc prec) =
219encodeBinop (name, Binop comment tipe assoc prec) =
215− Encode.object
220+ E.object
216− [ "name" ==> Encode.text name
221+ [ "name" ==> E.text name
217− , "comment" ==> Encode.text comment
222+ , "comment" ==> E.text comment
218 , "type" ==> Type.encode tipe
223 , "type" ==> Type.encode tipe
219 , "associativity" ==> encodeAssoc assoc
224 , "associativity" ==> encodeAssoc assoc
220 , "precedence" ==> encodePrec prec
225 , "precedence" ==> encodePrec prec
221 ]
226 ]
222
227
223
228
224−binop :: Decode.Decoder Binop
229+binop :: D.Decoder Error Binop
225binop =
230binop =
226 Binop
231 Binop
227− <$> Decode.field "comment" Decode.text
232+ <$> D.field "comment" D.text
228− <*> Decode.field "type" Type.decoder
233+ <*> D.field "type" typeDecoder
229− <*> Decode.field "associativity" assocDecoder
234+ <*> D.field "associativity" assocDecoder
230− <*> Decode.field "precedence" precDecoder
235+ <*> D.field "precedence" precDecoder
231
236
232
237
233
238
234-- ASSOCIATIVITY JSON
239-- ASSOCIATIVITY JSON
235
240
236
241
237−encodeAssoc :: Binop.Associativity -> Encode.Value
242+encodeAssoc :: Binop.Associativity -> E.Value
238encodeAssoc assoc =
243encodeAssoc assoc =
239 case assoc of
244 case assoc of
240− Binop.Left -> Encode.text "left"
245+ Binop.Left -> E.text "left"
241− Binop.Non -> Encode.text "non"
246+ Binop.Non -> E.text "non"
242− Binop.Right -> Encode.text "right"
247+ Binop.Right -> E.text "right"
243
248
244
249
245−assocDecoder :: Decode.Decoder Binop.Associativity
250+assocDecoder :: D.Decoder Error Binop.Associativity
246assocDecoder =
251assocDecoder =
247− do txt <- Decode.text
252+ do txt <- D.text
248 case txt of
253 case txt of
249− "left" -> Decode.succeed Binop.Left
254+ "left" -> D.succeed Binop.Left
250− "non" -> Decode.succeed Binop.Non
255+ "non" -> D.succeed Binop.Non
251− "right" -> Decode.succeed Binop.Right
256+ "right" -> D.succeed Binop.Right
252− _ -> Decode.fail "Expecting an ASSOCIATIVITY (e.g. left, non, right)"
257+ _ -> D.fail BadAssociativity
253
258
254
259
255
260
256-- PRECEDENCE JSON
261-- PRECEDENCE JSON
257
262
258
263
259−encodePrec :: Binop.Precedence -> Encode.Value
264+encodePrec :: Binop.Precedence -> E.Value
260encodePrec (Binop.Precedence n) =
265encodePrec (Binop.Precedence n) =
261− Encode.int n
266+ E.int n
262
267
263
268
264−precDecoder :: Decode.Decoder Binop.Precedence
269+precDecoder :: D.Decoder Error Binop.Precedence
265precDecoder =
270precDecoder =
266− Binop.Precedence <$> Decode.int
271+ Binop.Precedence <$> D.int
267
272
268
273
269
274
src/Elm/Package.hs+6−6
@@ -4,7 +4,7 @@ module Elm.Package
4 ( Name(..)
4 ( Name(..)
5 , Package(..)
5 , Package(..)
6 , isKernel
6 , isKernel
7− , toString, toUrl, toFilePath
7+ , toString, toText, toUrl, toFilePath
8 , fromText
8 , fromText
9 , dummyName, kernel, core
9 , dummyName, kernel, core
10 , browser, virtualDom, html
10 , browser, virtualDom, html
@@ -36,7 +36,7 @@ import qualified Data.Text.Lazy.Builder.Int as B (decimal)
36import Data.Text (Text)
36import Data.Text (Text)
37import Data.Word (Word16)
37import Data.Word (Word16)
38import System.FilePath ((</>))
38import System.FilePath ((</>))
39−import qualified Json.Decode as Decode
39+import qualified Json.Decode.Internals as Decode
40import qualified Json.Encode as Encode
40import qualified Json.Encode as Encode
41
41
42
42
@@ -316,12 +316,12 @@ instance Binary Version where
316-- JSON
316-- JSON
317
317
318
318
319−decoder :: Decode.Decoder Name
319+decoder :: Decode.Decoder String Name
320decoder =
320decoder =
321 do txt <- Decode.text
321 do txt <- Decode.text
322 case fromText txt of
322 case fromText txt of
323 Left msg ->
323 Left msg ->
324− Decode.fail $ "Expecting a PACKAGE name. " ++ msg
324+ Decode.fail msg
325
325
326 Right name ->
326 Right name ->
327 Decode.succeed name
327 Decode.succeed name
@@ -333,7 +333,7 @@ encode name =
333
333
334
334
335
335
336−versionDecoder :: Decode.Decoder Version
336+versionDecoder :: Decode.Decoder String Version
337versionDecoder =
337versionDecoder =
338 do txt <- Decode.text
338 do txt <- Decode.text
339 case versionFromText txt of
339 case versionFromText txt of
@@ -341,7 +341,7 @@ versionDecoder =
341 Decode.succeed version
341 Decode.succeed version
342
342
343 Left msg ->
343 Left msg ->
344− Decode.fail $ "Expecting a VERSION. " ++ msg
344+ Decode.fail msg
345
345
346
346
347encodeVersion :: Version -> Encode.Value
347encodeVersion :: Version -> Encode.Value
src/Json/Decode.hs+199−252
@@ -1,320 +1,267 @@
1−{-# OPTIONS_GHC -Wall #-}
1+{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
2−{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE BangPatterns, MagicHash, OverloadedStrings, UnboxedTuples #-}
3module Json.Decode
3module Json.Decode
4+ ( parse
5+ -- re-export from Json.Decode.Internals
4− ( Decoder, Error(..), decode, parse
6+ , Json.Decoder, Json.Error(..)
5− , string, text, bool, int, float
7+ , Json.string, Json.text, Json.bool, Json.int
6− , list, dict, maybe
8+ , Json.list, Json.dict, Json.maybe
7− , field, at
9+ , Json.field, Json.at
8− , index
10+ , Json.index
11+ , Json.map, Json.map2
12+ , Json.succeed, Json.fail
9− , map, map2, succeed, fail, andThen, oneOf
13+ , Json.andThen, Json.oneOf
10− , aeson
11 )
14 )
12 where
15 where
13
16
14
17
15−import Data.Text (Text)
16−import Prelude hiding (fail, map, maybe)
18+import Prelude hiding (length)
17−
18−import qualified Control.Monad as Monad
19−import qualified Data.Aeson as Aeson
20−import qualified Data.ByteString.Lazy as BS
19+import qualified Data.ByteString.Internal as B
21−import qualified Data.HashMap.Lazy as HashMap
20+import qualified Data.HashMap.Strict as HashMap
22−import qualified Data.Scientific as Scientific
23import qualified Data.Text as Text
21import qualified Data.Text as Text
22+import qualified Data.Text.Encoding as Text
24import qualified Data.Vector as Vector
23import qualified Data.Vector as Vector
25−import Data.Vector ((!?))
24+import Foreign.ForeignPtr (ForeignPtr)
26−
25+import GHC.Word (Word8(..))
27−
28−
29−-- DECODERS
30
26
27+import qualified Json.Decode.Internals as Json
28+import qualified Parse.Primitives as P
29+import qualified Parse.Primitives.Internals as I
30+import Parse.Primitives.Internals (Parser(..), State(..), noError)
31+import qualified Parse.Primitives.Keyword as Keyword
32+import qualified Parse.Primitives.Symbol as Symbol
33+import qualified Reporting.Error.Syntax as E
34+import qualified Reporting.Region as R
31
35
32−data Decoder a =
33− Decoder
34− { _run :: (Error -> Error) -> Aeson.Value -> Either Error a
35− }
36
36
37
37
38−data Error
38+-- PARSE
39− = Field Text Error
40− | Index Int Error
41− | OneOf [Error]
42− | Failure Aeson.Value String
43− deriving (Show)
44
39
45
40
46−decode :: Decoder a -> Aeson.Value -> Either Error a
41+data Result e a
47−decode decoder value =
42+ = BadJson E.Error
48− _run decoder id value
43+ | BadContent (Json.Error e)
44+ | Success a
49
45
50
46
51−parse :: Decoder a -> BS.ByteString -> Either (Maybe Error) a
47+parse :: Json.Decoder e a -> B.ByteString -> Result e a
52−parse decoder bytestring =
48+parse (Json.Decoder run) bytestring =
53− case Aeson.eitherDecode bytestring of
49+ case P.run jsonFile bytestring of
54− Left _ ->
50+ Left err ->
55− Left Nothing
51+ BadJson err
56
52
57− Right json ->
53+ Right value ->
58− case decode decoder json of
54+ case run id value of
59 Left err ->
55 Left err ->
60− Left (Just err)
56+ BadContent err
61−
57+
62− Right value ->
58+ Right answer ->
63− Right value
59+ Success answer
64−
60+
65−
61+
66−
62+
67−-- PRIMITIVES
63+-- JSON
68−
64+
69−
65+
70−string :: Decoder String
66+jsonFile :: Parser Json.Value
71−string =
67+jsonFile =
72− Text.unpack <$> text
68+ do spaces
73−
69+ value <- jsonValue
74−
70+ spaces
75−text :: Decoder Text
71+ P.endOfFile
76−text =
72+ return value
77− Decoder $ \mkError value ->
78− case value of
79− Aeson.String txt ->
80− Right txt
81−
82− _ ->
83− Left (mkError (Failure value "Expecting a STRING"))
84−
85−
86−bool :: Decoder Bool
87−bool =
88− Decoder $ \mkError value ->
89− case value of
90− Aeson.Bool boolean ->
91− Right boolean
92−
93− _ ->
94− Left (mkError (Failure value "Expecting a BOOL"))
95−
96−
97−int :: Decoder Int
98−int =
99− Decoder $ \mkError value ->
100− case value of
101− Aeson.Number number ->
102− case Scientific.toBoundedInteger number of
103− Nothing ->
104− Left (mkError (Failure value "Expecting an INT"))
105−
106− Just integer ->
107− Right integer
108−
109− _ ->
110− Left (mkError (Failure value "Expecting an INT"))
111−
112−
113−float :: Decoder Float
114−float =
115− Decoder $ \mkError value ->
116− case value of
117− Aeson.Number number ->
118− Right (Scientific.toRealFloat number)
119−
120− _ ->
121− Left (mkError (Failure value "Expecting a FLOAT"))
122−
123−
124−
125−-- DATA STRUCTURES
126−
127−
128−list :: Decoder a -> Decoder [a]
129−list (Decoder run) =
130− Decoder $ \mkError value ->
131− case value of
132− Aeson.Array vector ->
133− Vector.toList <$>
134− Vector.imapM (\i v -> run (mkError . Index i) v) vector
135−
136− _ ->
137− Left (mkError (Failure value "Expecting an ARRAY"))
138−
139
73
140−dict :: Decoder a -> Decoder (HashMap.HashMap Text a)
141−dict (Decoder run) =
142− Decoder $ \mkError value ->
143− case value of
144− Aeson.Object hashMap ->
145− HashMap.traverseWithKey (\k v -> run (mkError . Field k) v) hashMap
146
74
147− _ ->
75+jsonValue :: Parser Json.Value
148− Left (mkError (Failure value "Expecting an OBJECT"))
76+jsonValue =
77+ do start <- P.getPosition
78+ I.oneOf
79+ [ Json.String <$> string
80+ , object start
81+ , array start
82+ , number
83+ , Keyword.jsonTrue >> return Json.TRUE
84+ , Keyword.jsonFalse >> return Json.FALSE
85+ , Keyword.jsonNull >> return Json.NULL
86+ ]
149
87
150
88
151−maybe :: Decoder a -> Decoder (Maybe a)
152−maybe (Decoder run) =
153− Decoder $ \mkError value ->
154− case run mkError value of
155− Left _ ->
156− Right Nothing
157
89
158− Right a ->
90+-- OBJECT
159− Right (Just a)
160
91
161
92
93+object :: R.Position -> Parser Json.Value
94+object start =
95+ do Symbol.leftCurly
96+ P.inContext start E.ExprRecord $
97+ do spaces
98+ I.oneOf
99+ [ do entry <- field
100+ spaces
101+ objectHelp [entry]
102+ , do Symbol.rightCurly
103+ return (Json.Object [] HashMap.empty)
104+ ]
162
105
163−-- OBJECT PRIMITIVES
164
106
107+objectHelp :: [(Text.Text, Json.Value)] -> Parser Json.Value
108+objectHelp revEntries =
109+ I.oneOf
110+ [
111+ do Symbol.comma
112+ spaces
113+ entry <- field
114+ spaces
115+ objectHelp (entry:revEntries)
116+ ,
117+ do Symbol.rightCurly
118+ return (Json.Object (reverse revEntries) (HashMap.fromList revEntries))
119+ ]
165
120
166−field :: Text -> Decoder a -> Decoder a
167−field name (Decoder run) =
168− Decoder $ \mkError value ->
169− case value of
170− Aeson.Object hashMap ->
171− case HashMap.lookup name hashMap of
172− Just v ->
173− run (mkError . Field name) v
174
121
175− Nothing ->
122+field :: Parser (Text.Text, Json.Value)
176− Left $ mkError $ Failure value $
123+field =
177− "Expecting a \"" ++ Text.unpack name ++ "\" field."
124+ do key <- string
125+ spaces
126+ Symbol.hasType
127+ spaces
128+ value <- jsonValue
129+ return (key, value)
178
130
179− _ ->
180− Left (mkError (Failure value "Expecting an OBJECT"))
181
131
182
132
183−at :: [Text] -> Decoder a -> Decoder a
133+-- ARRAY
184−at names decoder =
185− foldr field decoder names
186
134
187
135
136+array :: R.Position -> Parser Json.Value
137+array start =
138+ do Symbol.leftSquare
139+ P.inContext start E.ExprList $
140+ do spaces
141+ I.oneOf
142+ [ do entry <- jsonValue
143+ spaces
144+ arrayHelp 1 [entry]
145+ , do Symbol.rightSquare
146+ return (Json.Array Vector.empty)
147+ ]
188
148
189−-- ARRAY PRIMITIVES
190
149
150+arrayHelp :: Int -> [Json.Value] -> Parser Json.Value
151+arrayHelp !length revEntries =
152+ I.oneOf
153+ [
154+ do Symbol.comma
155+ spaces
156+ entry <- jsonValue
157+ spaces
158+ arrayHelp (length + 1) (entry:revEntries)
159+ ,
160+ do Symbol.rightSquare
161+ return $ Json.Array $ Vector.reverse $
162+ Vector.fromListN length revEntries
163+ ]
191
164
192−index :: Int -> Decoder a -> Decoder a
193−index i (Decoder run) =
194− Decoder $ \mkError value ->
195− case value of
196− Aeson.Array vector ->
197− case vector !? i of
198− Just v ->
199− run (mkError . Index i) v
200−
201− Nothing ->
202− Left $ mkError $ Failure value $
203− "Expecting a longer ARRAY. I need index " ++ show i
204− ++ ", but the array only has " ++ show (Vector.length vector)
205− ++ " elements."
206−
207− _ ->
208− Left (mkError (Failure value "Expecting an ARRAY"))
209
165
210
166
167+-- NUMBER
211
168
212−-- MAPPING
213
169
170+number :: Parser Json.Value
171+number =
172+ error "TODO"
214
173
215−map :: (a -> value) -> Decoder a -> Decoder value
216−map func (Decoder run) =
217− Decoder $ \mkError value ->
218− func <$> run mkError value
219
174
220
175
221−map2 :: (a -> b -> value) -> Decoder a -> Decoder b -> Decoder value
176+-- STRING
222−map2 func (Decoder runA) (Decoder runB) =
223− Decoder $ \mkError value ->
224− func
225− <$> runA mkError value
226− <*> runB mkError value
227
177
228
178
229−apply :: Decoder (a -> b) -> Decoder a -> Decoder b
179+string :: Parser Text.Text
230−apply (Decoder runFunc) (Decoder runArg) =
180+string =
231− Decoder $ \mkError value ->
181+ Parser $ \(State fp offset terminal indent row col ctx) cok cerr _ eerr ->
232− do func <- runFunc mkError value
182+ if offset < terminal && I.unsafeIndex fp offset == 0x22 {- " -} then
233− arg <- runArg mkError value
234− return (func arg)
235−
236−
237−instance Functor Decoder where
238− fmap =
239− map
240−
241−
242−instance Applicative Decoder where
243− pure =
244− succeed
245−
246− (<*>) =
247− apply
248−
249−
250−instance Monad Decoder where
251− return =
252− succeed
253−
254− (>>=) decoder callback =
255− andThen callback decoder
256−
257− fail msg =
258− fail msg
259−
260
183
184+ case stringHelp fp (offset + 1) terminal row (col + 1) of
185+ Err err ->
186+ cerr err
261
187
262−-- FANCY PRIMITIVES
188+ Ok newOffset newRow newCol ->
189+ let
190+ !newState = State fp newOffset terminal indent newRow newCol ctx
191+ !content = Text.decodeUtf8 (B.PS fp offset (newOffset - offset))
192+ in
193+ cok content newState noError
263
194
195+ else
196+ eerr noError
264
197
265−succeed :: a -> Decoder a
266−succeed a =
267− Decoder $ \_ _ -> Right a
268
198
199+data StringResult
200+ = Err E.ParseError
201+ | Ok !Int !Int !Int
269
202
270−fail :: String -> Decoder a
271−fail msg =
272− Decoder $ \mkError value ->
273− Left (mkError (Failure value msg))
274
203
204+stringHelp :: ForeignPtr Word8 -> Int -> Int -> Int -> Int -> StringResult
205+stringHelp fp offset terminal row col =
206+ if offset >= terminal then
207+ Err (E.ParseError row col E.EndOfFile_String)
275
208
276−andThen :: (a -> Decoder b) -> Decoder a -> Decoder b
209+ else
277−andThen callback (Decoder runA) =
210+ case I.unsafeIndex fp offset of
278− Decoder $ \mkError value ->
211+ 0x22 {- " -} ->
279− do a <- runA mkError value
212+ Ok (offset + 1) row (col + 1)
280− let (Decoder runB) = callback a
281− runB mkError value
282
213
214+ 0x0A {- \n -} ->
215+ Err (E.ParseError row col E.NewLineInString)
283
216
217+ 0x5C {- \ -} ->
218+ let
219+ !offset1 = offset + 1
220+ in
221+ if offset1 < terminal then
284
222
285−-- ONE OF
223+ let
224+ !word = I.unsafeIndex fp offset1
225+ !newOffset = offset1 + I.getCharWidth fp offset1 terminal word
226+ in
227+ stringHelp fp newOffset terminal row (col + 2)
286
228
229+ else
230+ Err (E.ParseError (row + 1) col E.EndOfFile_String)
287
231
288−oneOf :: [Decoder a] -> Decoder a
232+ word ->
289−oneOf decoders =
233+ let !newOffset = offset + I.getCharWidth fp offset terminal word in
290− Decoder (oneOfHelp decoders [])
234+ stringHelp fp newOffset terminal row (col + 1)
291
235
292
236
293−oneOfHelp :: [Decoder a] -> [Error] -> (Error -> Error) -> Aeson.Value -> Either Error a
294−oneOfHelp decoders errors mkError value =
295− case decoders of
296− [] ->
297− Left (mkError (OneOf (reverse errors)))
298
237
299− Decoder run : otherDecoders ->
300− case run mkError value of
301− Right a ->
302− Right a
303
238
304− Left err ->
239+-- SPACES
305− oneOfHelp otherDecoders (err:errors) mkError value
306
240
307
241
242+spaces :: Parser ()
243+spaces =
244+ Parser $ \(State fp offset terminal indent row col ctx) cok _ _ _ ->
245+ let
246+ (# newOffset, newRow, newCol #) =
247+ eatSpaces fp offset terminal row col
308
248
309−-- AESON
249+ !newState =
250+ State fp newOffset terminal indent newRow newCol ctx
251+ in
252+ cok () newState noError
310
253
311
254
312−aeson :: (Aeson.FromJSON a) => Decoder a
255+eatSpaces :: ForeignPtr Word8 -> Int -> Int -> Int -> Int -> (# Int, Int, Int #)
313−aeson =
256+eatSpaces fp offset terminal row col =
314− Decoder $ \mkError value ->
257+ if offset >= terminal then
315− case Aeson.fromJSON value of
258+ (# offset, row, col #)
316− Aeson.Error msg ->
317− Left (mkError (Failure value msg))
318
259
319− Aeson.Success a ->
260+ else
320− Right a
261+ case I.unsafeIndex fp offset of
262+ 0x20 {- -} -> eatSpaces fp (offset + 1) terminal row (col + 1)
263+ 0x09 {- \t -} -> eatSpaces fp (offset + 1) terminal row (col + 1)
264+ 0x0A {- \n -} -> eatSpaces fp (offset + 1) terminal (row + 1) 1
265+ 0x0D {- \r -} -> eatSpaces fp (offset + 1) terminal row col
266+ _ ->
267+ (# offset, row, col #)
src/Json/Decode/Internals.hsnew file+316
@@ -0,0 +1,316 @@
1+{-# OPTIONS_GHC -Wall #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+module Json.Decode.Internals
4+ ( Value(..)
5+ , Decoder(..)
6+ , Error(..)
7+ , string, text, bool, int
8+ , list, dict, pairs
9+ , maybe
10+ , field, at
11+ , index
12+ , map, map2, mapError
13+ , succeed, fail
14+ , andThen, oneOf
15+ )
16+ where
17+
18+
19+import Data.Text (Text)
20+import Prelude hiding (fail, map, maybe)
21+
22+import qualified Data.HashMap.Strict as HashMap
23+import qualified Data.Text as Text
24+import qualified Data.Vector as Vector
25+import Data.Vector ((!?))
26+
27+
28+
29+-- VALUE
30+
31+
32+data Value
33+ = Array (Vector.Vector Value)
34+ | Object [(Text, Value)] (HashMap.HashMap Text Value)
35+ | String Text
36+ | TRUE
37+ | FALSE
38+ | Integer Int
39+ | NULL
40+
41+
42+
43+-- DECODERS
44+
45+
46+newtype Decoder e a =
47+ Decoder
48+ { _run :: (Error e -> Error e) -> Value -> Either (Error e) a
49+ }
50+
51+
52+data Error e
53+ = Field Text (Error e)
54+ | Index Int (Error e)
55+ | OneOf [Error e]
56+ | Failure Value e
57+ | Expecting Value Type
58+
59+
60+data Type
61+ = TObject
62+ | TArray
63+ | TString
64+ | TBool
65+ | TInt
66+ | TObjectWith Text
67+ | TArrayWith Int Int
68+
69+
70+
71+-- PRIMITIVES
72+
73+
74+string :: Decoder e String
75+string =
76+ Text.unpack <$> text
77+
78+
79+text :: Decoder e Text
80+text =
81+ Decoder $ \mkError value ->
82+ case value of
83+ String txt ->
84+ Right txt
85+
86+ _ ->
87+ Left (mkError (Expecting value TString))
88+
89+
90+bool :: Decoder e Bool
91+bool =
92+ Decoder $ \mkError value ->
93+ case value of
94+ TRUE ->
95+ Right True
96+
97+ FALSE ->
98+ Right False
99+
100+ _ ->
101+ Left (mkError (Expecting value TBool))
102+
103+
104+int :: Decoder e Int
105+int =
106+ Decoder $ \mkError value ->
107+ case value of
108+ Integer integer ->
109+ Right integer
110+
111+ _ ->
112+ Left (mkError (Expecting value TInt))
113+
114+
115+
116+-- DATA STRUCTURES
117+
118+
119+list :: Decoder e a -> Decoder e [a]
120+list (Decoder run) =
121+ Decoder $ \mkError value ->
122+ case value of
123+ Array vector ->
124+ Vector.toList <$>
125+ Vector.imapM (\i v -> run (mkError . Index i) v) vector
126+
127+ _ ->
128+ Left (mkError (Expecting value TArray))
129+
130+
131+dict :: Decoder e a -> Decoder e (HashMap.HashMap Text a)
132+dict (Decoder run) =
133+ Decoder $ \mkError value ->
134+ case value of
135+ Object _ hashMap ->
136+ HashMap.traverseWithKey (\k v -> run (mkError . Field k) v) hashMap
137+
138+ _ ->
139+ Left (mkError (Expecting value TObject))
140+
141+
142+pairs :: Decoder e a -> Decoder e [(Text, a)]
143+pairs (Decoder run) =
144+ Decoder $ \mkError value ->
145+ case value of
146+ Object kvs _ ->
147+ traverse (\(k,v) -> (,) k <$> run (mkError . Field k) v) kvs
148+
149+ _ ->
150+ Left (mkError (Expecting value TObject))
151+
152+
153+maybe :: Decoder e a -> Decoder e (Maybe a)
154+maybe (Decoder run) =
155+ Decoder $ \mkError value ->
156+ case run mkError value of
157+ Left _ ->
158+ Right Nothing
159+
160+ Right a ->
161+ Right (Just a)
162+
163+
164+
165+-- OBJECT PRIMITIVES
166+
167+
168+field :: Text -> Decoder e a -> Decoder e a
169+field name (Decoder run) =
170+ Decoder $ \mkError value ->
171+ case value of
172+ Object _ hashMap ->
173+ case HashMap.lookup name hashMap of
174+ Just v ->
175+ run (mkError . Field name) v
176+
177+ Nothing ->
178+ Left $ mkError $ Expecting value (ObjectWith name)
179+
180+ _ ->
181+ Left (mkError (Expecting value TObject))
182+
183+
184+at :: [Text] -> Decoder e a -> Decoder e a
185+at names decoder =
186+ foldr field decoder names
187+
188+
189+
190+-- ARRAY PRIMITIVES
191+
192+
193+index :: Int -> Decoder e a -> Decoder e a
194+index i (Decoder run) =
195+ Decoder $ \mkError value ->
196+ case value of
197+ Array vector ->
198+ case vector !? i of
199+ Just v ->
200+ run (mkError . Index i) v
201+
202+ Nothing ->
203+ Left $ mkError $ Expecting value $ ArrayWith i (Vector.length vector)
204+
205+ _ ->
206+ Left (mkError (Expecting value TArray))
207+
208+
209+
210+-- MAPPING
211+
212+
213+map :: (a -> value) -> Decoder e a -> Decoder e value
214+map func (Decoder run) =
215+ Decoder $ \mkError value ->
216+ func <$> run mkError value
217+
218+
219+map2 :: (a -> b -> value) -> Decoder e a -> Decoder e b -> Decoder e value
220+map2 func (Decoder runA) (Decoder runB) =
221+ Decoder $ \mkError value ->
222+ func
223+ <$> runA mkError value
224+ <*> runB mkError value
225+
226+
227+mapError :: (e -> e') -> Decoder e a -> Decoder e' a
228+mapError func (Decoder run) =
229+ Decoder $ \mkError value ->
230+ run (mapErrorHelp func . mkError) value
231+
232+
233+mapErrorHelp :: (e -> e') -> Error e -> Error e'
234+mapErrorHelp func err =
235+ case err of
236+ Field f subErr -> Field f (mapErrorHelp func subErr)
237+ Index i subErr -> Index i (mapErrorHelp func subErr)
238+ OneOf errors -> OneOf (map (mapErrorHelp func) errors)
239+ Failure v e -> Failure v (func e)
240+ Expecting v e -> Expecting v e
241+
242+
243+apply :: Decoder e (a -> b) -> Decoder e a -> Decoder e b
244+apply (Decoder runFunc) (Decoder runArg) =
245+ Decoder $ \mkError value ->
246+ do func <- runFunc mkError value
247+ arg <- runArg mkError value
248+ return (func arg)
249+
250+
251+instance Functor (Decoder e) where
252+ fmap =
253+ map
254+
255+
256+instance Applicative (Decoder e) where
257+ pure =
258+ succeed
259+
260+ (<*>) =
261+ apply
262+
263+
264+instance Monad (Decoder e) where
265+ return =
266+ succeed
267+
268+ (>>=) decoder callback =
269+ andThen callback decoder
270+
271+
272+
273+-- FANCY PRIMITIVES
274+
275+
276+succeed :: a -> Decoder e a
277+succeed a =
278+ Decoder $ \_ _ -> Right a
279+
280+
281+fail :: e -> Decoder e a
282+fail err =
283+ Decoder $ \mkError value ->
284+ Left (mkError (Failure value err))
285+
286+
287+andThen :: (a -> Decoder e b) -> Decoder e a -> Decoder e b
288+andThen callback (Decoder runA) =
289+ Decoder $ \mkError value ->
290+ do a <- runA mkError value
291+ let (Decoder runB) = callback a
292+ runB mkError value
293+
294+
295+
296+-- ONE OF
297+
298+
299+oneOf :: [Decoder e a] -> Decoder e a
300+oneOf decoders =
301+ Decoder (oneOfHelp decoders [])
302+
303+
304+oneOfHelp :: [Decoder e a] -> [Error e] -> (Error e -> Error e) -> Value -> Either (Error e) a
305+oneOfHelp decoders errors mkError value =
306+ case decoders of
307+ [] ->
308+ Left (mkError (OneOf (reverse errors)))
309+
310+ Decoder run : otherDecoders ->
311+ case run mkError value of
312+ Right a ->
313+ Right a
314+
315+ Left err ->
316+ oneOfHelp otherDecoders (err:errors) mkError value
src/Parse/Primitives/Keyword.hs+23
@@ -8,6 +8,7 @@ module Parse.Primitives.Keyword
8 , infix_, left_, right_, non_
8 , infix_, left_, right_, non_
9 , module_, import_, exposing_, as_, where_, effect_
9 , module_, import_, exposing_, as_, where_, effect_
10 , command_, subscription_
10 , command_, subscription_
11+ , jsonTrue, jsonFalse, jsonNull
11 )
12 )
12 where
13 where
13
14
@@ -210,3 +211,25 @@ command_ =
210subscription_ :: Parser ()
211subscription_ :: Parser ()
211subscription_ =
212subscription_ =
212 keyword "subscription"
213 keyword "subscription"
214+
215+
216+
217+-- JSON
218+
219+
220+{-# NOINLINE jsonTrue #-}
221+jsonTrue :: Parser ()
222+jsonTrue =
223+ keyword "true"
224+
225+
226+{-# NOINLINE jsonFalse #-}
227+jsonFalse :: Parser ()
228+jsonFalse =
229+ keyword "false"
230+
231+
232+{-# NOINLINE jsonNull #-}
233+jsonNull :: Parser ()
234+jsonNull =
235+ keyword "null"