module Bookhound.Format.Operations.Finder (Finder(..)) where import Bookhound.Parser (runParser) import Bookhound.ParserCombinators (IsMatch (..), (<|>), (|*)) import Bookhound.Parsers.Char (dot) import Bookhound.Parsers.Number (unsignedInt) import Bookhound.Parsers.String (withinSquareBrackets) import Bookhound.Format.SyntaxTrees.Json (JsonExpression (..)) import Bookhound.Format.SyntaxTrees.Toml (TomlExpression (..)) import Bookhound.Format.SyntaxTrees.Yaml (YamlExpression (..)) import Data.Either (fromRight) import Data.Maybe (listToMaybe) import qualified Data.Map as Map import Data.Text (pack) class Finder a where toList :: a -> [(String, a)] findAll :: ((String, a) -> Bool) -> a -> [a] find :: ((String, a) -> Bool) -> a -> Maybe a findByKeys :: [String] -> a -> Maybe a findByPath :: String -> a -> Maybe a findAll (String, a) -> Bool f = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap forall a b. (a, b) -> b snd forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. (a -> Bool) -> [a] -> [a] filter (String, a) -> Bool f forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. Finder a => a -> [(String, a)] toList find (String, a) -> Bool f = forall a. [a] -> Maybe a listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. Finder a => ((String, a) -> Bool) -> a -> [a] findAll (String, a) -> Bool f findByKeys [] a expr = forall a. a -> Maybe a Just a expr findByKeys (String x : [String] xs) a expr = forall {a}. Finder a => String -> a -> Maybe a findByKey String x a expr forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= forall a. Finder a => [String] -> a -> Maybe a findByKeys [String] xs where findByKey :: String -> a -> Maybe a findByKey String key = forall a. Finder a => ((String, a) -> Bool) -> a -> Maybe a find (\(String str, a _) -> String str forall a. Eq a => a -> a -> Bool == String key) findByPath String path = forall a. Finder a => [String] -> a -> Maybe a findByKeys [String] pathSeq where pathSeq :: [String] pathSeq = forall b a. b -> Either a b -> b fromRight [] forall a b. (a -> b) -> a -> b $ forall a. Parser a -> Input -> Either ParseError a runParser Parser [String] parsePath forall a b. (a -> b) -> a -> b $ String -> Input pack String path parsePath :: Parser [String] parsePath = forall a. IsMatch a => a -> Parser a is Char '$' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> ((Parser String index forall a. Parser a -> Parser a -> Parser a <|> Parser String key) |*) index :: Parser String index = forall a. Show a => a -> String show forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall b. Parser b -> Parser b withinSquareBrackets Parser Integer unsignedInt key :: Parser String key = Parser Char dot forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Parser String word word :: Parser String word = (forall a. IsMatch a => [a] -> Parser a noneOf [Char '.', Char '['] |*) instance Finder JsonExpression where toList :: JsonExpression -> [(String, JsonExpression)] toList = \case nil :: JsonExpression nil@JsonExpression JsNull -> [(String "", JsonExpression nil)] n :: JsonExpression n@(JsNumber Double _) -> [(String "", JsonExpression n)] bool :: JsonExpression bool@(JsBool Bool _) -> [(String "", JsonExpression bool)] str :: JsonExpression str@(JsString String _) -> [(String "", JsonExpression str)] JsArray [JsonExpression] arr -> forall a b. [a] -> [b] -> [(a, b)] zip (forall a. Show a => a -> String show forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Int 0 .. forall (t :: * -> *) a. Foldable t => t a -> Int length [JsonExpression] arr forall a. Num a => a -> a -> a - Int 1]) [JsonExpression] arr JsObject Map String JsonExpression obj -> forall k a. Map k a -> [(k, a)] Map.toList Map String JsonExpression obj instance Finder YamlExpression where toList :: YamlExpression -> [(String, YamlExpression)] toList = \case nil :: YamlExpression nil@YamlExpression YamlNull -> [(String "", YamlExpression nil)] n :: YamlExpression n@(YamlInteger Integer _) -> [(String "", YamlExpression n)] n :: YamlExpression n@(YamlFloat Double _) -> [(String "", YamlExpression n)] bool :: YamlExpression bool@(YamlBool Bool _) -> [(String "", YamlExpression bool)] str :: YamlExpression str@(YamlString String _) -> [(String "", YamlExpression str)] date :: YamlExpression date@(YamlDate Day _) -> [(String "", YamlExpression date)] time :: YamlExpression time@(YamlTime TimeOfDay _) -> [(String "", YamlExpression time)] dateTime :: YamlExpression dateTime@(YamlDateTime ZonedTime _) -> [(String "", YamlExpression dateTime)] YamlList CollectionType _ [YamlExpression] arr -> forall a b. [a] -> [b] -> [(a, b)] zip (forall a. Show a => a -> String show forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Int 0 .. forall (t :: * -> *) a. Foldable t => t a -> Int length [YamlExpression] arr forall a. Num a => a -> a -> a - Int 1]) [YamlExpression] arr YamlMap CollectionType _ Map String YamlExpression obj -> forall k a. Map k a -> [(k, a)] Map.toList Map String YamlExpression obj instance Finder TomlExpression where toList :: TomlExpression -> [(String, TomlExpression)] toList = \case nil :: TomlExpression nil@TomlExpression TomlNull -> [(String "", TomlExpression nil)] n :: TomlExpression n@(TomlInteger Integer _) -> [(String "", TomlExpression n)] n :: TomlExpression n@(TomlFloat Double _) -> [(String "", TomlExpression n)] bool :: TomlExpression bool@(TomlBool Bool _) -> [(String "", TomlExpression bool)] str :: TomlExpression str@(TomlString String _) -> [(String "", TomlExpression str)] date :: TomlExpression date@(TomlDate Day _) -> [(String "", TomlExpression date)] time :: TomlExpression time@(TomlTime TimeOfDay _) -> [(String "", TomlExpression time)] dateTime :: TomlExpression dateTime@(TomlDateTime ZonedTime _) -> [(String "", TomlExpression dateTime)] TomlArray [TomlExpression] arr -> forall a b. [a] -> [b] -> [(a, b)] zip (forall a. Show a => a -> String show forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Int 0 .. forall (t :: * -> *) a. Foldable t => t a -> Int length [TomlExpression] arr forall a. Num a => a -> a -> a - Int 1]) [TomlExpression] arr TomlTable TableType _ Map String TomlExpression obj -> forall k a. Map k a -> [(k, a)] Map.toList Map String TomlExpression obj