on master help sign in
Stop relying on aeson, parse JSON with my parser

This has two major benefits: 1. I can keep track of field order in objects. 2. I can give nice parse errors on missing commas, unclosed strings, etc. This is not too hard to do, and (1) will allow having headers to explain the exposed modules better. E.g. the core library can have headers for container modules, error modules, effect modules, etc.

commit00a30697dd9db5cdde3717bbbc5d7fd7838e1807 authorEvan Czaplicki <evancz@users.noreply.github.com> dateSat 20 Jan 2018, 16:49 (9 years ago) parent51e95e8
8 files changed+636−337
elm-compiler.cabal+1−1 src/Elm/Compiler/Module.hs+6−2 src/Elm/Compiler/Type.hs+6−2 src/Elm/Docs.hs+79−74 src/Elm/Package.hs+6−6 src/Json/Decode.hs+199−252 src/Json/Decode/Internals.hs+316 src/Parse/Primitives/Keyword.hs+23
elm-compiler.cabal+1−1
@@ -91,6 +91,7 @@ Library
9191 Generate.JavaScript.Builder,
9292 Generate.JavaScript.Expression,
9393 Generate.JavaScript.Name,
94+ Json.Decode.Internals,
9495 Nitpick.PatternMatches,
9596 Nitpick.TopLevelTypes,
9697 Optimize.Case,
@@ -146,7 +147,6 @@ Library
146147 Paths_elm_compiler
147148
148149 Build-depends:
149− aeson >= 0.11,
150150 ansi-terminal >= 0.7 && < 0.8,
151151 ansi-wl-pprint >= 0.6.7 && < 0.7,
152152 base >=4.8 && <5,
src/Elm/Compiler/Module.hs+6−2
@@ -14,6 +14,7 @@ module Elm.Compiler.Module
1414 , dehyphenate
1515 , encode
1616 , decoder
17+ , Error(..)
1718
1819 -- canonical names
1920 , ModuleName.Canonical(..)
@@ -98,12 +99,15 @@ encode =
9899 Encode.text
99100
100101
101−decoder :: Decode.Decoder Raw
102+data Error = BadModuleName
103+
104+
105+decoder :: Decode.Decoder Error Raw
102106decoder =
103107 do txt <- Decode.text
104108 case nameFromText txt of
105109 Nothing ->
106− Decode.fail "Expecting a module name like \"Html.Events\""
110+ Decode.fail BadModuleName
107111
108112 Just name ->
109113 Decode.succeed name
src/Elm/Compiler/Type.hs+6−2
@@ -8,6 +8,7 @@ module Elm.Compiler.Type
88 , Alias(..)
99 , Union(..)
1010 , encode
11+ , Error(..)
1112 , decoder
1213 , encodeMetadata
1314 )
@@ -187,12 +188,15 @@ encode tipe =
187188 Encode.text (Text.pack (toString OneLine tipe))
188189
189190
190−decoder :: Decode.Decoder Type
191+data Error = BadType
192+
193+
194+decoder :: Decode.Decoder Error Type
191195decoder =
192196 do txt <- Decode.text
193197 case Parse.run Type.expression (Text.encodeUtf8 (Text.replace "'" "_" txt)) of
194198 Left _ ->
195− Decode.fail "Expecting a type, like (String -> Int)"
199+ Decode.fail BadType
196200
197201 Right (tipe, _, _) ->
198202 Decode.succeed (fromRawType tipe)
src/Elm/Docs.hs+79−74
@@ -33,8 +33,8 @@ import qualified Elm.Compiler.Module as Module
3333import qualified Elm.Compiler.Type as Type
3434import qualified Elm.Compiler.Type.Extract as Extract
3535import qualified Elm.Name as N
36−import qualified Json.Decode as Decode
37−import qualified Json.Encode as Encode
36+import qualified Json.Decode as D
37+import qualified Json.Encode as E
3838import Json.Encode ((==>))
3939import qualified Reporting.Annotation as A
4040import qualified Reporting.Error as Error
@@ -95,175 +95,180 @@ data Binop = Binop Comment Type.Type Binop.Associativity Binop.Precedence
9595-- JSON ENCODE / DECODE
9696
9797
98−encode :: Module -> Encode.Value
98+encode :: Module -> E.Value
9999encode (Module name comment unions aliases values binops) =
100− Encode.object $
100+ E.object $
101101 [ "name" ==> Module.encode name
102− , "comment" ==> Encode.text comment
103− , "unions" ==> Encode.list encodeUnion (Map.toList unions)
104− , "aliases" ==> Encode.list encodeAlias (Map.toList aliases)
105− , "values" ==> Encode.list encodeValue (Map.toList values)
106− , "binops" ==> Encode.list encodeBinop (Map.toList binops)
102+ , "comment" ==> E.text comment
103+ , "unions" ==> E.list encodeUnion (Map.toList unions)
104+ , "aliases" ==> E.list encodeAlias (Map.toList aliases)
105+ , "values" ==> E.list encodeValue (Map.toList values)
106+ , "binops" ==> E.list encodeBinop (Map.toList binops)
107107 ]
108108
109109
110−decoder :: Decode.Decoder Module
110+decoder :: D.Decoder Error Module
111111decoder =
112112 Module
113− <$> Decode.field "name" Module.decoder
114− <*> Decode.field "comment" Decode.text
115− <*> Decode.field "unions" (dictDecoder union)
116− <*> Decode.field "aliases" (dictDecoder alias)
117− <*> Decode.field "values" (dictDecoder value)
118− <*> Decode.field "binops" (dictDecoder binop)
113+ <$> D.field "name" Module.decoder
114+ <*> D.field "comment" D.text
115+ <*> D.field "unions" (dictDecoder union)
116+ <*> D.field "aliases" (dictDecoder alias)
117+ <*> D.field "values" (dictDecoder value)
118+ <*> D.field "binops" (dictDecoder binop)
119119
120120
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)
122122dictDecoder entryDecoder =
123− Map.fromList <$> Decode.list (named entryDecoder)
123+ Map.fromList <$> D.list (named entryDecoder)
124124
125125
126−named :: Decode.Decoder a -> Decode.Decoder (N.Name, a)
126+named :: D.Decoder Error a -> D.Decoder Error (N.Name, a)
127127named entryDecoder =
128128 (,)
129− <$> Decode.field "name" Decode.text
129+ <$> D.field "name" D.text
130130 <*> entryDecoder
131131
132132
133+data Error
134+ = BadAssociativity
135+ | BadType
136+
137+
133138
134139-- UNION JSON
135140
136141
137−encodeUnion :: (N.Name, Union) -> Encode.Value
142+encodeUnion :: (N.Name, Union) -> E.Value
138143encodeUnion (name, Union comment args cases) =
139− Encode.object
140− [ "name" ==> Encode.text name
141− , "comment" ==> Encode.text comment
142− , "args" ==> Encode.list Encode.text args
143− , "cases" ==> Encode.list encodeCase cases
144+ E.object
145+ [ "name" ==> E.text name
146+ , "comment" ==> E.text comment
147+ , "args" ==> E.list E.text args
148+ , "cases" ==> E.list encodeCase cases
144149 ]
145150
146151
147−union :: Decode.Decoder Union
152+union :: D.Decoder Error Union
148153union =
149154 Union
150− <$> Decode.field "comment" Decode.text
151− <*> Decode.field "args" (Decode.list Decode.text)
152− <*> Decode.field "cases" (Decode.list caseDecoder)
155+ <$> D.field "comment" D.text
156+ <*> D.field "args" (D.list D.text)
157+ <*> D.field "cases" (D.list caseDecoder)
153158
154159
155−encodeCase :: ( N.Name, [Type.Type] ) -> Encode.Value
160+encodeCase :: ( N.Name, [Type.Type] ) -> E.Value
156161encodeCase ( 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 ]
158163
159164
160−caseDecoder :: Decode.Decoder ( N.Name, [Type.Type] )
165+caseDecoder :: D.Decoder Error ( N.Name, [Type.Type] )
161166caseDecoder =
162167 (,)
163− <$> Decode.index 0 Decode.text
164− <*> Decode.index 1 (Decode.list Type.decoder)
168+ <$> D.index 0 D.text
169+ <*> D.index 1 (D.list typeDecoder)
165170
166171
167172
168173-- ALIAS JSON
169174
170175
171−encodeAlias :: (N.Name, Alias) -> Encode.Value
176+encodeAlias :: (N.Name, Alias) -> E.Value
172177encodeAlias ( name, Alias comment args tipe) =
173− Encode.object
174− [ "name" ==> Encode.text name
175− , "comment" ==> Encode.text comment
176− , "args" ==> Encode.list Encode.text args
178+ E.object
179+ [ "name" ==> E.text name
180+ , "comment" ==> E.text comment
181+ , "args" ==> E.list E.text args
177182 , "type" ==> Type.encode tipe
178183 ]
179184
180185
181−alias :: Decode.Decoder Alias
186+alias :: D.Decoder Error Alias
182187alias =
183188 Alias
184− <$> Decode.field "comment" Decode.text
185− <*> Decode.field "args" (Decode.list Decode.text)
186− <*> Decode.field "type" Type.decoder
189+ <$> D.field "comment" D.text
190+ <*> D.field "args" (D.list D.text)
191+ <*> D.field "type" typeDecoder
187192
188193
189194
190195-- VALUE JSON
191196
192197
193−encodeValue :: (N.Name, Value) -> Encode.Value
198+encodeValue :: (N.Name, Value) -> E.Value
194199encodeValue (name, Value comment tipe) =
195− Encode.object
196− [ "name" ==> Encode.text name
197− , "comment" ==> Encode.text comment
200+ E.object
201+ [ "name" ==> E.text name
202+ , "comment" ==> E.text comment
198203 , "type" ==> Type.encode tipe
199204 ]
200205
201206
202−value :: Decode.Decoder Value
207+value :: D.Decoder Error Value
203208value =
204209 Value
205− <$> Decode.field "comment" Decode.text
206− <*> Decode.field "type" Type.decoder
210+ <$> D.field "comment" D.text
211+ <*> D.field "type" typeDecoder
207212
208213
209214
210215-- BINOP JSON
211216
212217
213−encodeBinop :: (N.Name, Binop) -> Encode.Value
218+encodeBinop :: (N.Name, Binop) -> E.Value
214219encodeBinop (name, Binop comment tipe assoc prec) =
215− Encode.object
216− [ "name" ==> Encode.text name
217− , "comment" ==> Encode.text comment
220+ E.object
221+ [ "name" ==> E.text name
222+ , "comment" ==> E.text comment
218223 , "type" ==> Type.encode tipe
219224 , "associativity" ==> encodeAssoc assoc
220225 , "precedence" ==> encodePrec prec
221226 ]
222227
223228
224−binop :: Decode.Decoder Binop
229+binop :: D.Decoder Error Binop
225230binop =
226231 Binop
227− <$> Decode.field "comment" Decode.text
228− <*> Decode.field "type" Type.decoder
229− <*> Decode.field "associativity" assocDecoder
230− <*> Decode.field "precedence" precDecoder
232+ <$> D.field "comment" D.text
233+ <*> D.field "type" typeDecoder
234+ <*> D.field "associativity" assocDecoder
235+ <*> D.field "precedence" precDecoder
231236
232237
233238
234239-- ASSOCIATIVITY JSON
235240
236241
237−encodeAssoc :: Binop.Associativity -> Encode.Value
242+encodeAssoc :: Binop.Associativity -> E.Value
238243encodeAssoc assoc =
239244 case assoc of
240− Binop.Left -> Encode.text "left"
241− Binop.Non -> Encode.text "non"
242− Binop.Right -> Encode.text "right"
245+ Binop.Left -> E.text "left"
246+ Binop.Non -> E.text "non"
247+ Binop.Right -> E.text "right"
243248
244249
245−assocDecoder :: Decode.Decoder Binop.Associativity
250+assocDecoder :: D.Decoder Error Binop.Associativity
246251assocDecoder =
247− do txt <- Decode.text
252+ do txt <- D.text
248253 case txt of
249− "left" -> Decode.succeed Binop.Left
250− "non" -> Decode.succeed Binop.Non
251− "right" -> Decode.succeed Binop.Right
252− _ -> Decode.fail "Expecting an ASSOCIATIVITY (e.g. left, non, right)"
254+ "left" -> D.succeed Binop.Left
255+ "non" -> D.succeed Binop.Non
256+ "right" -> D.succeed Binop.Right
257+ _ -> D.fail BadAssociativity
253258
254259
255260
256261-- PRECEDENCE JSON
257262
258263
259−encodePrec :: Binop.Precedence -> Encode.Value
264+encodePrec :: Binop.Precedence -> E.Value
260265encodePrec (Binop.Precedence n) =
261− Encode.int n
266+ E.int n
262267
263268
264−precDecoder :: Decode.Decoder Binop.Precedence
269+precDecoder :: D.Decoder Error Binop.Precedence
265270precDecoder =
266− Binop.Precedence <$> Decode.int
271+ Binop.Precedence <$> D.int
267272
268273
269274
src/Elm/Package.hs+6−6
@@ -4,7 +4,7 @@ module Elm.Package
44 ( Name(..)
55 , Package(..)
66 , isKernel
7− , toString, toUrl, toFilePath
7+ , toString, toText, toUrl, toFilePath
88 , fromText
99 , dummyName, kernel, core
1010 , browser, virtualDom, html
@@ -36,7 +36,7 @@ import qualified Data.Text.Lazy.Builder.Int as B (decimal)
3636import Data.Text (Text)
3737import Data.Word (Word16)
3838import System.FilePath ((</>))
39−import qualified Json.Decode as Decode
39+import qualified Json.Decode.Internals as Decode
4040import qualified Json.Encode as Encode
4141
4242
@@ -316,12 +316,12 @@ instance Binary Version where
316316-- JSON
317317
318318
319−decoder :: Decode.Decoder Name
319+decoder :: Decode.Decoder String Name
320320decoder =
321321 do txt <- Decode.text
322322 case fromText txt of
323323 Left msg ->
324− Decode.fail $ "Expecting a PACKAGE name. " ++ msg
324+ Decode.fail msg
325325
326326 Right name ->
327327 Decode.succeed name
@@ -333,7 +333,7 @@ encode name =
333333
334334
335335
336−versionDecoder :: Decode.Decoder Version
336+versionDecoder :: Decode.Decoder String Version
337337versionDecoder =
338338 do txt <- Decode.text
339339 case versionFromText txt of
@@ -341,7 +341,7 @@ versionDecoder =
341341 Decode.succeed version
342342
343343 Left msg ->
344− Decode.fail $ "Expecting a VERSION. " ++ msg
344+ Decode.fail msg
345345
346346
347347encodeVersion :: Version -> Encode.Value
src/Json/Decode.hs+199−252
@@ -1,320 +1,267 @@
1−{-# OPTIONS_GHC -Wall #-}
2−{-# LANGUAGE OverloadedStrings #-}
1+{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
2+{-# LANGUAGE BangPatterns, MagicHash, OverloadedStrings, UnboxedTuples #-}
33module Json.Decode
4− ( Decoder, Error(..), decode, parse
5− , string, text, bool, int, float
6− , list, dict, maybe
7− , field, at
8− , index
9− , map, map2, succeed, fail, andThen, oneOf
10− , aeson
4+ ( parse
5+ -- re-export from Json.Decode.Internals
6+ , Json.Decoder, Json.Error(..)
7+ , Json.string, Json.text, Json.bool, Json.int
8+ , Json.list, Json.dict, Json.maybe
9+ , Json.field, Json.at
10+ , Json.index
11+ , Json.map, Json.map2
12+ , Json.succeed, Json.fail
13+ , Json.andThen, Json.oneOf
1114 )
1215 where
1316
1417
15−import Data.Text (Text)
16−import Prelude hiding (fail, map, maybe)
17−
18−import qualified Control.Monad as Monad
19−import qualified Data.Aeson as Aeson
20−import qualified Data.ByteString.Lazy as BS
21−import qualified Data.HashMap.Lazy as HashMap
22−import qualified Data.Scientific as Scientific
18+import Prelude hiding (length)
19+import qualified Data.ByteString.Internal as B
20+import qualified Data.HashMap.Strict as HashMap
2321import qualified Data.Text as Text
22+import qualified Data.Text.Encoding as Text
2423import qualified Data.Vector as Vector
25−import Data.Vector ((!?))
26−
27−
28−
29−-- DECODERS
24+import Foreign.ForeignPtr (ForeignPtr)
25+import GHC.Word (Word8(..))
3026
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
3135
32−data Decoder a =
33− Decoder
34− { _run :: (Error -> Error) -> Aeson.Value -> Either Error a
35− }
3636
3737
38−data Error
39− = Field Text Error
40− | Index Int Error
41− | OneOf [Error]
42− | Failure Aeson.Value String
43− deriving (Show)
38+-- PARSE
4439
4540
46−decode :: Decoder a -> Aeson.Value -> Either Error a
47−decode decoder value =
48− _run decoder id value
41+data Result e a
42+ = BadJson E.Error
43+ | BadContent (Json.Error e)
44+ | Success a
4945
5046
51−parse :: Decoder a -> BS.ByteString -> Either (Maybe Error) a
52−parse decoder bytestring =
53− case Aeson.eitherDecode bytestring of
54− Left _ ->
55− Left Nothing
47+parse :: Json.Decoder e a -> B.ByteString -> Result e a
48+parse (Json.Decoder run) bytestring =
49+ case P.run jsonFile bytestring of
50+ Left err ->
51+ BadJson err
5652
57− Right json ->
58− case decode decoder json of
53+ Right value ->
54+ case run id value of
5955 Left err ->
60− Left (Just err)
61−
62− Right value ->
63− Right value
64−
65−
66−
67−-- PRIMITIVES
68−
69−
70−string :: Decoder String
71−string =
72− Text.unpack <$> text
73−
74−
75−text :: Decoder Text
76−text =
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−
56+ BadContent err
57+
58+ Right answer ->
59+ Success answer
60+
61+
62+
63+-- JSON
64+
65+
66+jsonFile :: Parser Json.Value
67+jsonFile =
68+ do spaces
69+ value <- jsonValue
70+ spaces
71+ P.endOfFile
72+ return value
13973
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
14674
147− _ ->
148− Left (mkError (Failure value "Expecting an OBJECT"))
75+jsonValue :: Parser Json.Value
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+ ]
14987
15088
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
15789
158− Right a ->
159− Right (Just a)
90+-- OBJECT
16091
16192
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+ ]
162105
163−-- OBJECT PRIMITIVES
164106
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+ ]
165120
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
174121
175− Nothing ->
176− Left $ mkError $ Failure value $
177− "Expecting a \"" ++ Text.unpack name ++ "\" field."
122+field :: Parser (Text.Text, Json.Value)
123+field =
124+ do key <- string
125+ spaces
126+ Symbol.hasType
127+ spaces
128+ value <- jsonValue
129+ return (key, value)
178130
179− _ ->
180− Left (mkError (Failure value "Expecting an OBJECT"))
181131
182132
183−at :: [Text] -> Decoder a -> Decoder a
184−at names decoder =
185− foldr field decoder names
133+-- ARRAY
186134
187135
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+ ]
188148
189−-- ARRAY PRIMITIVES
190149
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+ ]
191164
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"))
209165
210166
167+-- NUMBER
211168
212−-- MAPPING
213169
170+number :: Parser Json.Value
171+number =
172+ error "TODO"
214173
215−map :: (a -> value) -> Decoder a -> Decoder value
216−map func (Decoder run) =
217− Decoder $ \mkError value ->
218− func <$> run mkError value
219174
220175
221−map2 :: (a -> b -> value) -> Decoder a -> Decoder b -> Decoder value
222−map2 func (Decoder runA) (Decoder runB) =
223− Decoder $ \mkError value ->
224− func
225− <$> runA mkError value
226− <*> runB mkError value
176+-- STRING
227177
228178
229−apply :: Decoder (a -> b) -> Decoder a -> Decoder b
230−apply (Decoder runFunc) (Decoder runArg) =
231− Decoder $ \mkError value ->
232− do func <- runFunc mkError value
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−
179+string :: Parser Text.Text
180+string =
181+ Parser $ \(State fp offset terminal indent row col ctx) cok cerr _ eerr ->
182+ if offset < terminal && I.unsafeIndex fp offset == 0x22 {- " -} then
260183
184+ case stringHelp fp (offset + 1) terminal row (col + 1) of
185+ Err err ->
186+ cerr err
261187
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
263194
195+ else
196+ eerr noError
264197
265−succeed :: a -> Decoder a
266−succeed a =
267− Decoder $ \_ _ -> Right a
268198
199+data StringResult
200+ = Err E.ParseError
201+ | Ok !Int !Int !Int
269202
270−fail :: String -> Decoder a
271−fail msg =
272− Decoder $ \mkError value ->
273− Left (mkError (Failure value msg))
274203
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)
275208
276−andThen :: (a -> Decoder b) -> Decoder a -> Decoder b
277−andThen callback (Decoder runA) =
278− Decoder $ \mkError value ->
279− do a <- runA mkError value
280− let (Decoder runB) = callback a
281− runB mkError value
209+ else
210+ case I.unsafeIndex fp offset of
211+ 0x22 {- " -} ->
212+ Ok (offset + 1) row (col + 1)
282213
214+ 0x0A {- \n -} ->
215+ Err (E.ParseError row col E.NewLineInString)
283216
217+ 0x5C {- \ -} ->
218+ let
219+ !offset1 = offset + 1
220+ in
221+ if offset1 < terminal then
284222
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)
286228
229+ else
230+ Err (E.ParseError (row + 1) col E.EndOfFile_String)
287231
288−oneOf :: [Decoder a] -> Decoder a
289−oneOf decoders =
290− Decoder (oneOfHelp decoders [])
232+ word ->
233+ let !newOffset = offset + I.getCharWidth fp offset terminal word in
234+ stringHelp fp newOffset terminal row (col + 1)
291235
292236
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)))
298237
299− Decoder run : otherDecoders ->
300− case run mkError value of
301− Right a ->
302− Right a
303238
304− Left err ->
305− oneOfHelp otherDecoders (err:errors) mkError value
239+-- SPACES
306240
307241
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
308248
309−-- AESON
249+ !newState =
250+ State fp newOffset terminal indent newRow newCol ctx
251+ in
252+ cok () newState noError
310253
311254
312−aeson :: (Aeson.FromJSON a) => Decoder a
313−aeson =
314− Decoder $ \mkError value ->
315− case Aeson.fromJSON value of
316− Aeson.Error msg ->
317− Left (mkError (Failure value msg))
255+eatSpaces :: ForeignPtr Word8 -> Int -> Int -> Int -> Int -> (# Int, Int, Int #)
256+eatSpaces fp offset terminal row col =
257+ if offset >= terminal then
258+ (# offset, row, col #)
318259
319− Aeson.Success a ->
320− Right a
260+ else
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
88 , infix_, left_, right_, non_
99 , module_, import_, exposing_, as_, where_, effect_
1010 , command_, subscription_
11+ , jsonTrue, jsonFalse, jsonNull
1112 )
1213 where
1314
@@ -210,3 +211,25 @@ command_ =
210211subscription_ :: Parser ()
211212subscription_ =
212213 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"