@@ -26,8 +26,10 @@ module Data.Aeson.Types.Internal
26 -- * Type conversion
26 -- * Type conversion
28 , Result(..)
28 , Result(..)
29 , JSONPathElement(..)
30 , JSONPathElement(..)
30 , JSONPath
31 , JSONPath
32 , parseEither
34 , parseEither
33 , parseMaybe
35 , parseMaybe
@@ -80,8 +82,13 @@ data JSONPathElement = Key Text
80 deriving (Eq, Show, Typeable)
82 deriving (Eq, Show, Typeable)
81type JSONPath = [JSONPathElement]
83type JSONPath = [JSONPathElement]
85+-- | The internal result of running a 'Parser'.
86+data IResult a = IError JSONPath String
88+ deriving (Eq, Show, Typeable)
83-- | The result of running a 'Parser'.
90-- | The result of running a 'Parser'.
84−data Result a = Error JSONPath String
91+data Result a = Error String
85 | Success a
92 | Success a
86 deriving (Eq, Show, Typeable)
93 deriving (Eq, Show, Typeable)
@@ -89,28 +96,57 @@ instance NFData JSONPathElement where
89 rnf (Key t) = rnf t
96 rnf (Key t) = rnf t
90 rnf (Index i) = rnf i
97 rnf (Index i) = rnf i
99+instance (NFData a) => NFData (IResult a) where
100+ rnf (ISuccess a) = rnf a
101+ rnf (IError path err) = rnf path `seq` rnf err
92instance (NFData a) => NFData (Result a) where
103instance (NFData a) => NFData (Result a) where
93 rnf (Success a) = rnf a
104 rnf (Success a) = rnf a
94− rnf (Error path err) = rnf path `seq` rnf err
105+ rnf (Error err) = rnf err
107+instance Functor IResult where
108+ fmap f (ISuccess a) = ISuccess (f a)
109+ fmap _ (IError path err) = IError path err
96instance Functor Result where
112instance Functor Result where
97 fmap f (Success a) = Success (f a)
113 fmap f (Success a) = Success (f a)
98− fmap _ (Error path err) = Error path err
114+ fmap _ (Error err) = Error err
99 {-# INLINE fmap #-}
115 {-# INLINE fmap #-}
117+instance Monad IResult where
119+ {-# INLINE return #-}
120+ ISuccess a >>= k = k a
121+ IError path err >>= _ = IError path err
122+ {-# INLINE (>>=) #-}
101instance Monad Result where
124instance Monad Result where
102 return = Success
125 return = Success
103 {-# INLINE return #-}
126 {-# INLINE return #-}
104− Success a >>= k = k a
127+ Success a >>= k = k a
105− Error path err >>= _ = Error path err
128+ Error err >>= _ = Error err
106 {-# INLINE (>>=) #-}
129 {-# INLINE (>>=) #-}
131+instance Applicative IResult where
135+ {-# INLINE (<*>) #-}
108instance Applicative Result where
137instance Applicative Result where
109 pure = return
138 pure = return
110 {-# INLINE pure #-}
139 {-# INLINE pure #-}
111 (<*>) = ap
140 (<*>) = ap
112 {-# INLINE (<*>) #-}
141 {-# INLINE (<*>) #-}
143+instance MonadPlus IResult where
144+ mzero = fail "mzero"
145+ {-# INLINE mzero #-}
146+ mplus a@(ISuccess _) _ = a
148+ {-# INLINE mplus #-}
114instance MonadPlus Result where
150instance MonadPlus Result where
115 mzero = fail "mzero"
151 mzero = fail "mzero"
116 {-# INLINE mzero #-}
152 {-# INLINE mzero #-}
@@ -118,12 +154,24 @@ instance MonadPlus Result where
118 mplus _ b = b
154 mplus _ b = b
119 {-# INLINE mplus #-}
155 {-# INLINE mplus #-}
157+instance Alternative IResult where
159+ {-# INLINE empty #-}
161+ {-# INLINE (<|>) #-}
121instance Alternative Result where
163instance Alternative Result where
122 empty = mzero
164 empty = mzero
123 {-# INLINE empty #-}
165 {-# INLINE empty #-}
124 (<|>) = mplus
166 (<|>) = mplus
125 {-# INLINE (<|>) #-}
167 {-# INLINE (<|>) #-}
169+instance Monoid (IResult a) where
170+ mempty = fail "mempty"
171+ {-# INLINE mempty #-}
173+ {-# INLINE mappend #-}
127instance Monoid (Result a) where
175instance Monoid (Result a) where
128 mempty = fail "mempty"
176 mempty = fail "mempty"
129 {-# INLINE mempty #-}
177 {-# INLINE mempty #-}
@@ -288,9 +336,14 @@ emptyObject = Object H.empty
289-- | Run a 'Parser'.
337-- | Run a 'Parser'.
290parse :: (a -> Parser b) -> a -> Result b
338parse :: (a -> Parser b) -> a -> Result b
291−parse m v = runParser (m v) [] Error Success
339+parse m v = runParser (m v) [] (const Error) Success
292{-# INLINE parse #-}
340{-# INLINE parse #-}
343+iparse :: (a -> Parser b) -> a -> IResult b
344+iparse m v = runParser (m v) [] IError ISuccess
345+{-# INLINE iparse #-}
294-- | Run a 'Parser' with a 'Maybe' result type.
347-- | Run a 'Parser' with a 'Maybe' result type.
295parseMaybe :: (a -> Parser b) -> a -> Maybe b
348parseMaybe :: (a -> Parser b) -> a -> Maybe b
296parseMaybe m v = runParser (m v) [] (\_ _ -> Nothing) Just
349parseMaybe m v = runParser (m v) [] (\_ _ -> Nothing) Just
@@ -298,18 +351,18 @@ parseMaybe m v = runParser (m v) [] (\_ _ -> Nothing) Just
299-- | Run a 'Parser' with an 'Either' result type.
352-- | Run a 'Parser' with an 'Either' result type.
300parseEither :: (a -> Parser b) -> a -> Either String b
353parseEither :: (a -> Parser b) -> a -> Either String b
354+parseEither m v = runParser (m v) [] onError Right
301−parseEither m v = runParser (m v) [] (\path msg -> Left $ formatError path msg) Right
355+ where onError path msg = Left (formatError path msg)
302{-# INLINE parseEither #-}
356{-# INLINE parseEither #-}
304−-- | Annotate error message with JSON Path error location
358+-- | Annotate an error message with a
359+-- <http://goessner.net/articles/JsonPath/ JSONPath> error location.
305formatError :: JSONPath -> String -> String
360formatError :: JSONPath -> String -> String
306−formatError path msg = "Error in " ++ (formatJSONPath path) ++ ": " ++ msg
361+formatError path msg = "Error in " ++ (format "$" path) ++ ": " ++ msg
307− where formatJSONPath :: JSONPath -> String
362+ where
308− formatJSONPath p = format "$" p
363+ format pfx [] = pfx
309− where format :: String -> JSONPath -> String
310− format prefix [] = prefix
311− format prefix (Index idx:parts) = format (prefix ++ "[" ++ show idx ++ "]") parts
364+ format pfx (Index idx:parts) = format (pfx ++ "[" ++ show idx ++ "]") parts
312− format prefix (Key key:parts) = format (prefix ++ "." ++ unpack key) parts
365+ format pfx (Key key:parts) = format (pfx ++ "." ++ unpack key) parts
314-- | A key\/value pair for an 'Object'.
367-- | A key\/value pair for an 'Object'.
315type Pair = (Text, Value)
368type Pair = (Text, Value)