@@ -67,7 +67,7 @@ import Control.DeepSeq (NFData(..))
67import Control.Monad (MonadPlus(..), ap)
67import Control.Monad (MonadPlus(..), ap)
68import qualified Control.Monad.Fail as Fail
68import qualified Control.Monad.Fail as Fail
69import Data.ByteString.Builder (Builder, char7, toLazyByteString)
69import Data.ByteString.Builder (Builder, char7, toLazyByteString)
70−import Data.Char (isLower, isUpper, toLower)
70+import Data.Char (isLower, isUpper, toLower, isAlpha, isAlphaNum)
71import Data.Data (Data)
71import Data.Data (Data)
72import Data.HashMap.Strict (HashMap)
72import Data.HashMap.Strict (HashMap)
73import Data.Hashable (Hashable(..))
73import Data.Hashable (Hashable(..))
@@ -459,9 +459,28 @@ parseEither m v = runParser (m v) [] onError Right
459formatError :: JSONPath -> String -> String
459formatError :: JSONPath -> String -> String
460formatError path msg = "Error in " ++ (format "$" path) ++ ": " ++ msg
460formatError path msg = "Error in " ++ (format "$" path) ++ ": " ++ msg
462+ format :: String -> JSONPath -> String
462 format pfx [] = pfx
463 format pfx [] = pfx
463 format pfx (Index idx:parts) = format (pfx ++ "[" ++ show idx ++ "]") parts
464 format pfx (Index idx:parts) = format (pfx ++ "[" ++ show idx ++ "]") parts
464− format pfx (Key key:parts) = format (pfx ++ "." ++ unpack key) parts
465+ format pfx (Key key:parts) = format (pfx ++ formatKey key) parts
467+ formatKey :: Text -> String
469+ | isIdentifierKey strKey = "." ++ strKey
470+ | otherwise = "['" ++ escapeKey strKey ++ "']"
471+ where strKey = unpack key
473+ isIdentifierKey :: String -> Bool
474+ isIdentifierKey [] = False
475+ isIdentifierKey (x:xs) = isAlpha x && all isAlphaNum xs
477+ escapeKey :: String -> String
478+ escapeKey = concatMap escapeChar
480+ escapeChar :: Char -> String
481+ escapeChar '\'' = "\\'"
482+ escapeChar '\\' = "\\\\"
466-- | A key\/value pair for an 'Object'.
485-- | A key\/value pair for an 'Object'.
467type Pair = (Text, Value)
486type Pair = (Text, Value)