@@ -123,9 +123,9 @@ objectValues str val = do
123123 -- Why use acc pattern here, you may ask? because 'H.fromList' use 'unsafeInsert'
124124 -- and it's much faster because it's doing in place update to the 'HashMap'!
125125 loop acc = do
126− k <- str <* skipSpace <* char ':'
127− v <- val <* skipSpace
128− ch <- A.satisfy $ \w -> w == COMMA || w == CLOSE_CURLY
126+ k <- (str A.<?> "object key") <* skipSpace <* (char ':' A.<?> "':'")
127+ v <- (val A.<?> "object value") <* skipSpace
128+ ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_CURLY) A.<?> "',' or '}'"
129129 let acc' = (k, v) : acc
130130 if ch == COMMA
131131 then skipSpace >> loop acc'
@@ -149,8 +149,8 @@ arrayValues val = do
149149 else loop [] 1
150150 where
151151 loop acc !len = do
152− v <- val <* skipSpace
153− ch <- A.satisfy $ \w -> w == COMMA || w == CLOSE_SQUARE
152+ v <- (val A.<?> "json list value") <* skipSpace
153+ ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_SQUARE) A.<?> "',' or ']'"
154154 if ch == COMMA
155155 then skipSpace >> loop (v:acc) (len+1)
156156 else return (Vector.reverse (Vector.fromListN len (v:acc)))
@@ -275,7 +275,12 @@ eitherDecodeWith p to s =
275275 L.Done _ v -> case to v of
276276 ISuccess a -> Right a
277277 IError path msg -> Left (path, msg)
278− L.Fail _ _ msg -> Left ([], msg)
278+ L.Fail _ ctx msg -> Left ([], buildMsg ctx msg)
279+ where
280+ buildMsg :: [String] -> String -> String
281+ buildMsg [] msg = msg
282+ buildMsg (expectation:_) msg =
283+ msg ++ ". Expecting " ++ expectation
279284{-# INLINE eitherDecodeWith #-}
280285
281286eitherDecodeStrictWith :: Parser Value -> (Value -> IResult a) -> B.ByteString