{-# OPTIONS_GHC -Wno-unused-do-bind #-} module Data.Aeson.JSONPath.Parser.Query ( pRootQuery , pCurrentQuery ) where import qualified Data.Text as T import qualified Text.ParserCombinators.Parsec as P import Data.Functor (($>)) import Data.Maybe (isNothing) import Text.ParserCombinators.Parsec ((<|>)) import Data.Aeson.JSONPath.Parser.Filter (pFilter) import Data.Aeson.JSONPath.Parser.Name import Data.Aeson.JSONPath.Parser.Number import Data.Aeson.JSONPath.Parser.Common import Data.Aeson.JSONPath.Types import Prelude pRootQuery :: P.Parser Query pRootQuery :: Parser Query pRootQuery = do Char -> ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => Char -> ParsecT s u m Char P.char Char '$' segs <- ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity [QuerySegment Query] forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a] P.many (ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity [QuerySegment Query]) -> ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity [QuerySegment Query] forall a b. (a -> b) -> a -> b $ ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity (QuerySegment Query) forall tok st a. GenParser tok st a -> GenParser tok st a P.try ParsecT String () Identity (QuerySegment Query) pSpacedOutSegments return $ Query { queryType = Root, querySegments = segs } where pQ :: Parser Query pQ = Parser Query -> Parser Query forall tok st a. GenParser tok st a -> GenParser tok st a P.try Parser Query pRootQuery Parser Query -> Parser Query -> Parser Query forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> Parser Query -> Parser Query forall tok st a. GenParser tok st a -> GenParser tok st a P.try Parser Query pCurrentQuery pSpacedOutSegments :: ParsecT String () Identity (QuerySegment Query) pSpacedOutSegments = Parser String pSpaces Parser String -> ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity (QuerySegment Query) forall a b. ParsecT String () Identity a -> ParsecT String () Identity b -> ParsecT String () Identity b forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Parser Query -> ParsecT String () Identity (QuerySegment Query) forall a. Parser a -> Parser (QuerySegment a) pQuerySegment Parser Query pQ pCurrentQuery :: P.Parser Query pCurrentQuery :: Parser Query pCurrentQuery = do Char -> ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => Char -> ParsecT s u m Char P.char Char '@' segs <- ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity [QuerySegment Query] forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a] P.many (ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity [QuerySegment Query]) -> ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity [QuerySegment Query] forall a b. (a -> b) -> a -> b $ ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity (QuerySegment Query) forall tok st a. GenParser tok st a -> GenParser tok st a P.try ParsecT String () Identity (QuerySegment Query) pSpacedOutSegments return $ Query { queryType = Current, querySegments = segs } where pQ :: Parser Query pQ = Parser Query -> Parser Query forall tok st a. GenParser tok st a -> GenParser tok st a P.try Parser Query pRootQuery Parser Query -> Parser Query -> Parser Query forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> Parser Query -> Parser Query forall tok st a. GenParser tok st a -> GenParser tok st a P.try Parser Query pCurrentQuery pSpacedOutSegments :: ParsecT String () Identity (QuerySegment Query) pSpacedOutSegments = Parser String pSpaces Parser String -> ParsecT String () Identity (QuerySegment Query) -> ParsecT String () Identity (QuerySegment Query) forall a b. ParsecT String () Identity a -> ParsecT String () Identity b -> ParsecT String () Identity b forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Parser Query -> ParsecT String () Identity (QuerySegment Query) forall a. Parser a -> Parser (QuerySegment a) pQuerySegment Parser Query pQ pQuerySegment :: P.Parser a -> P.Parser (QuerySegment a) pQuerySegment :: forall a. Parser a -> Parser (QuerySegment a) pQuerySegment Parser a pQ = do dotdot <- Parser String -> ParsecT String () Identity (Maybe String) forall s (m :: * -> *) t u a. Stream s m t => ParsecT s u m a -> ParsecT s u m (Maybe a) P.optionMaybe (Parser String -> Parser String forall tok st a. GenParser tok st a -> GenParser tok st a P.try (Parser String -> Parser String) -> Parser String -> Parser String forall a b. (a -> b) -> a -> b $ String -> Parser String forall s (m :: * -> *) u. Stream s m Char => String -> ParsecT s u m String P.string String "..") seg <- pSegment pQ $ isNothing dotdot let segType = if Maybe String -> Bool forall a. Maybe a -> Bool isNothing Maybe String dotdot then SegmentType Child else SegmentType Descendant return $ QuerySegment { segmentType = segType, segment = seg } pSegment :: P.Parser a -> Bool -> P.Parser (Segment a) pSegment :: forall a. Parser a -> Bool -> Parser (Segment a) pSegment Parser a pQ Bool isChild = GenParser Char () (Segment a) -> GenParser Char () (Segment a) forall tok st a. GenParser tok st a -> GenParser tok st a P.try (Parser a -> GenParser Char () (Segment a) forall a. Parser a -> Parser (Segment a) pBracketed Parser a pQ) GenParser Char () (Segment a) -> GenParser Char () (Segment a) -> GenParser Char () (Segment a) forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> GenParser Char () (Segment a) -> GenParser Char () (Segment a) forall tok st a. GenParser tok st a -> GenParser tok st a P.try (Bool -> GenParser Char () (Segment a) forall a. Bool -> Parser (Segment a) pDotted Bool isChild) GenParser Char () (Segment a) -> GenParser Char () (Segment a) -> GenParser Char () (Segment a) forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> GenParser Char () (Segment a) -> GenParser Char () (Segment a) forall tok st a. GenParser tok st a -> GenParser tok st a P.try (Bool -> GenParser Char () (Segment a) forall a. Bool -> Parser (Segment a) pWildcardSeg Bool isChild) pBracketed :: P.Parser a -> P.Parser (Segment a) pBracketed :: forall a. Parser a -> Parser (Segment a) pBracketed Parser a pQ = do Char -> ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => Char -> ParsecT s u m Char P.char Char '[' Parser String pSpaces sel <- Parser a -> Parser (Selector a) forall a. Parser a -> Parser (Selector a) pSelector Parser a pQ optionalSels <- P.many $ pCommaSepSelectors pQ pSpaces P.char ']' return $ Bracketed (sel:optionalSels) where pCommaSepSelectors :: P.Parser a -> P.Parser (Selector a) pCommaSepSelectors :: forall a. Parser a -> Parser (Selector a) pCommaSepSelectors Parser a p = GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall tok st a. GenParser tok st a -> GenParser tok st a P.try (GenParser Char () (Selector a) -> GenParser Char () (Selector a)) -> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall a b. (a -> b) -> a -> b $ Parser String pSpaces Parser String -> ParsecT String () Identity Char -> ParsecT String () Identity Char forall a b. ParsecT String () Identity a -> ParsecT String () Identity b -> ParsecT String () Identity b forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Char -> ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => Char -> ParsecT s u m Char P.char Char ',' ParsecT String () Identity Char -> Parser String -> Parser String forall a b. ParsecT String () Identity a -> ParsecT String () Identity b -> ParsecT String () Identity b forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Parser String pSpaces Parser String -> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall a b. ParsecT String () Identity a -> ParsecT String () Identity b -> ParsecT String () Identity b forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Parser a -> GenParser Char () (Selector a) forall a. Parser a -> Parser (Selector a) pSelector Parser a p pDotted :: Bool -> P.Parser (Segment a) pDotted :: forall a. Bool -> Parser (Segment a) pDotted Bool isChild = do (if Bool isChild then String -> Parser String forall s (m :: * -> *) u. Stream s m Char => String -> ParsecT s u m String P.string String "." else String -> Parser String forall s (m :: * -> *) u. Stream s m Char => String -> ParsecT s u m String P.string String "") ParsecT String () Identity Char -> ParsecT String () Identity Char forall s (m :: * -> *) t u a. Stream s m t => ParsecT s u m a -> ParsecT s u m a P.lookAhead (ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char P.letter ParsecT String () Identity Char -> ParsecT String () Identity Char -> ParsecT String () Identity Char forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> String -> ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => String -> ParsecT s u m Char P.oneOf String "_" ParsecT String () Identity Char -> ParsecT String () Identity Char -> ParsecT String () Identity Char forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> ParsecT String () Identity Char pUnicodeChar) key <- String -> Text T.pack (String -> Text) -> Parser String -> ParsecT String () Identity Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> ParsecT String () Identity Char -> Parser String forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a] P.many1 (ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char P.alphaNum ParsecT String () Identity Char -> ParsecT String () Identity Char -> ParsecT String () Identity Char forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> String -> ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => String -> ParsecT s u m Char P.oneOf String "_" ParsecT String () Identity Char -> ParsecT String () Identity Char -> ParsecT String () Identity Char forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> ParsecT String () Identity Char pUnicodeChar) return $ Dotted key pWildcardSeg :: Bool -> P.Parser (Segment a) pWildcardSeg :: forall a. Bool -> Parser (Segment a) pWildcardSeg Bool isChild = (if Bool isChild then String -> Parser String forall s (m :: * -> *) u. Stream s m Char => String -> ParsecT s u m String P.string String "." else String -> Parser String forall s (m :: * -> *) u. Stream s m Char => String -> ParsecT s u m String P.string String "") Parser String -> ParsecT String () Identity Char -> ParsecT String () Identity Char forall a b. ParsecT String () Identity a -> ParsecT String () Identity b -> ParsecT String () Identity b forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Char -> ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => Char -> ParsecT s u m Char P.char Char '*' ParsecT String () Identity Char -> Segment a -> ParsecT String () Identity (Segment a) forall (f :: * -> *) a b. Functor f => f a -> b -> f b $> Segment a forall a. Segment a WildcardSegment pSelector :: P.Parser a -> P.Parser (Selector a) pSelector :: forall a. Parser a -> Parser (Selector a) pSelector Parser a pQ = GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall tok st a. GenParser tok st a -> GenParser tok st a P.try GenParser Char () (Selector a) forall a. Parser (Selector a) pName GenParser Char () (Selector a) -> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall tok st a. GenParser tok st a -> GenParser tok st a P.try GenParser Char () (Selector a) forall a. Parser (Selector a) pSlice GenParser Char () (Selector a) -> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall tok st a. GenParser tok st a -> GenParser tok st a P.try GenParser Char () (Selector a) forall a. Parser (Selector a) pIndex GenParser Char () (Selector a) -> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall tok st a. GenParser tok st a -> GenParser tok st a P.try GenParser Char () (Selector a) forall a. Parser (Selector a) pWildcardSel GenParser Char () (Selector a) -> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> GenParser Char () (Selector a) -> GenParser Char () (Selector a) forall tok st a. GenParser tok st a -> GenParser tok st a P.try (Parser a -> GenParser Char () (Selector a) forall a. Parser a -> Parser (Selector a) pFilter Parser a pQ) pName :: P.Parser (Selector a) pName :: forall a. Parser (Selector a) pName = Text -> Selector a forall a. Text -> Selector a Name (Text -> Selector a) -> (String -> Text) -> String -> Selector a forall b c a. (b -> c) -> (a -> b) -> a -> c . String -> Text T.pack (String -> Selector a) -> Parser String -> ParsecT String () Identity (Selector a) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (Parser String -> Parser String forall tok st a. GenParser tok st a -> GenParser tok st a P.try Parser String pSingleQuotted Parser String -> Parser String -> Parser String forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a <|> Parser String -> Parser String forall tok st a. GenParser tok st a -> GenParser tok st a P.try Parser String pDoubleQuotted) pIndex :: P.Parser (Selector a) pIndex :: forall a. Parser (Selector a) pIndex = Int -> Selector a forall a. Int -> Selector a Index (Int -> Selector a) -> ParsecT String () Identity Int -> ParsecT String () Identity (Selector a) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> ParsecT String () Identity Int pSignedInt pSlice :: P.Parser (Selector a) pSlice :: forall a. Parser (Selector a) pSlice = do start <- ParsecT String () Identity Int -> ParsecT String () Identity (Maybe Int) forall s (m :: * -> *) t u a. Stream s m t => ParsecT s u m a -> ParsecT s u m (Maybe a) P.optionMaybe (ParsecT String () Identity Int pSignedInt ParsecT String () Identity Int -> Parser String -> ParsecT String () Identity Int forall a b. ParsecT String () Identity a -> ParsecT String () Identity b -> ParsecT String () Identity a forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a <* Parser String pSpaces) P.char ':' pSpaces end <- P.optionMaybe (pSignedInt <* pSpaces) step <- P.optionMaybe (P.char ':' *> P.optionMaybe (pSpaces *> pSignedInt)) return $ ArraySlice (start, end, case step of Just (Just Int n) -> Int n Maybe (Maybe Int) _ -> Int 1) pWildcardSel :: P.Parser (Selector a) pWildcardSel :: forall a. Parser (Selector a) pWildcardSel = Char -> ParsecT String () Identity Char forall s (m :: * -> *) u. Stream s m Char => Char -> ParsecT s u m Char P.char Char '*' ParsecT String () Identity Char -> Selector a -> ParsecT String () Identity (Selector a) forall (f :: * -> *) a b. Functor f => f a -> b -> f b $> Selector a forall a. Selector a WildcardSelector