on master help sign in
Reduce code duplication.
commite75fc7310f885d4d12fd9e30bfe5c37726783304 authorBryan O'Sullivan <bos@serpentine.com> dateWed 30 Nov 2011, 10:41 (15 years ago) parentbe100f0
1 file changed+33−31
Data/Aeson/Parser.hs+33−31
Data/Aeson/Parser.hs+33−31
@@ -43,11 +43,7 @@ import qualified Data.HashMap.Strict as H
4343-- | Parse a top-level JSON value. This must be either an object or
4444-- an array.
4545json :: Parser Value
46−json = do
47− c <- skipSpace *> satisfy (`B8.elem` "{[")
48− if c == '{'
49− then object_
50− else array_
46+json = json_ object_ array_
5147
5248-- | Parse a top-level JSON value. This must be either an object or
5349-- an array.
@@ -56,43 +52,49 @@ json = do
5652-- building up thunks during parsing. Prefer this version if most of
5753-- the JSON data needs to be accessed.
5854json' :: Parser Value
59−json' = do
60− c <- skipSpace *> satisfy (`B8.elem` "{[")
61− if c == '{'
62− then object_'
63− else array_'
55+json' = json_ object_' array_'
56+
57+json_ :: Parser Value -> Parser Value -> Parser Value
58+json_ obj ary = do
59+ w <- skipSpace *> A.satisfy (\w -> w == 123 || w == 91)
60+ if w == 123
61+ then obj
62+ else ary
63+{-# INLINE json_ #-}
6464
6565object_ :: Parser Value
66−object_ = {-# SCC "object_" #-} do
67− skipSpace
68− let pair = do
69− a <- jstring <* skipSpace
70− b <- char ':' *> skipSpace *> value
71− return (a,b)
72− vals <- ((pair <* skipSpace) `sepBy` (char ',' *> skipSpace)) <* char '}'
73− return . Object $ H.fromList vals
66+object_ = {-# SCC "object_" #-} Object <$> objectValues value
7467
7568object_' :: Parser Value
7669object_' = {-# SCC "object_'" #-} do
70+ !vals <- objectValues value'
71+ return (Object vals)
72+
73+objectValues :: Parser Value -> Parser (H.HashMap Text Value)
74+objectValues val = do
7775 skipSpace
7876 let pair = do
7977 a <- jstring <* skipSpace
80− b <- char ':' *> skipSpace *> value'
78+ b <- char ':' *> skipSpace *> val
8179 return (a,b)
8280 vals <- ((pair <* skipSpace) `sepBy` (char ',' *> skipSpace)) <* char '}'
83− return $! Object $ H.fromList vals
81+ return (H.fromList vals)
82+{-# INLINE objectValues #-}
8483
8584array_ :: Parser Value
86−array_ = {-# SCC "array_" #-} do
87− skipSpace
88− vals <- ((value <* skipSpace) `sepBy` (char ',' *> skipSpace)) <* char ']'
89− return . Array $ Vector.fromList vals
85+array_ = {-# SCC "array_" #-} Array <$> arrayValues value
9086
9187array_' :: Parser Value
9288array_' = {-# SCC "array_'" #-} do
89+ !vals <- arrayValues value'
90+ return (Array vals)
91+
92+arrayValues :: Parser Value -> Parser (Vector Value)
93+arrayValues val = do
9394 skipSpace
94− vals <- ((value' <* skipSpace) `sepBy` (char ',' *> skipSpace)) <* char ']'
95− return $! Array $ Vector.fromList vals
95+ vals <- ((val <* skipSpace) `sepBy` (char ',' *> skipSpace)) <* char ']'
96+ return (Vector.fromList vals)
97+{-# INLINE arrayValues #-}
9698
9799-- | Parse any JSON value. Use 'json' in preference to this function
98100-- if you are parsing data from an untrusted source.
@@ -114,21 +116,21 @@ value = most <|> (Number <$> number)
114116value' :: Parser Value
115117value' = most <|> num
116118 where
117− num = do
118− n <- number
119− return $! Number n
120119 most = do
121120 c <- satisfy (`B8.elem` "{[\"ftn")
122121 case c of
123122 '{' -> object_'
124123 '[' -> array_'
125124 '"' -> do
126− s <- jstring_
127− return $! String s
125+ !s <- jstring_
126+ return (String s)
128127 'f' -> string "alse" *> pure (Bool False)
129128 't' -> string "rue" *> pure (Bool True)
130129 'n' -> string "ull" *> pure Null
131130 _ -> error "attoparsec panic! the impossible happened!"
131+ num = do
132+ !n <- number
133+ return (Number n)
132134
133135doubleQuote, backslash :: Word8
134136doubleQuote = 34