module Rattletrap.Type.Dictionary ( Dictionary(..) , dictionaryLookup ) where import Rattletrap.Type.Common import Rattletrap.Type.Str import qualified Control.Monad as Monad import qualified Data.Aeson as Json import qualified Data.Aeson.Types as Json import qualified Data.Map as Map import qualified Data.Text as Text data Dictionary a = DictionaryElement Str a (Dictionary a) | DictionaryEnd Str deriving (Dictionary a -> Dictionary a -> Bool (Dictionary a -> Dictionary a -> Bool) -> (Dictionary a -> Dictionary a -> Bool) -> Eq (Dictionary a) forall a. Eq a => Dictionary a -> Dictionary a -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Dictionary a -> Dictionary a -> Bool $c/= :: forall a. Eq a => Dictionary a -> Dictionary a -> Bool == :: Dictionary a -> Dictionary a -> Bool $c== :: forall a. Eq a => Dictionary a -> Dictionary a -> Bool Eq, Eq (Dictionary a) Eq (Dictionary a) -> (Dictionary a -> Dictionary a -> Ordering) -> (Dictionary a -> Dictionary a -> Bool) -> (Dictionary a -> Dictionary a -> Bool) -> (Dictionary a -> Dictionary a -> Bool) -> (Dictionary a -> Dictionary a -> Bool) -> (Dictionary a -> Dictionary a -> Dictionary a) -> (Dictionary a -> Dictionary a -> Dictionary a) -> Ord (Dictionary a) Dictionary a -> Dictionary a -> Bool Dictionary a -> Dictionary a -> Ordering Dictionary a -> Dictionary a -> Dictionary a forall a. Eq a -> (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a forall a. Ord a => Eq (Dictionary a) forall a. Ord a => Dictionary a -> Dictionary a -> Bool forall a. Ord a => Dictionary a -> Dictionary a -> Ordering forall a. Ord a => Dictionary a -> Dictionary a -> Dictionary a min :: Dictionary a -> Dictionary a -> Dictionary a $cmin :: forall a. Ord a => Dictionary a -> Dictionary a -> Dictionary a max :: Dictionary a -> Dictionary a -> Dictionary a $cmax :: forall a. Ord a => Dictionary a -> Dictionary a -> Dictionary a >= :: Dictionary a -> Dictionary a -> Bool $c>= :: forall a. Ord a => Dictionary a -> Dictionary a -> Bool > :: Dictionary a -> Dictionary a -> Bool $c> :: forall a. Ord a => Dictionary a -> Dictionary a -> Bool <= :: Dictionary a -> Dictionary a -> Bool $c<= :: forall a. Ord a => Dictionary a -> Dictionary a -> Bool < :: Dictionary a -> Dictionary a -> Bool $c< :: forall a. Ord a => Dictionary a -> Dictionary a -> Bool compare :: Dictionary a -> Dictionary a -> Ordering $ccompare :: forall a. Ord a => Dictionary a -> Dictionary a -> Ordering $cp1Ord :: forall a. Ord a => Eq (Dictionary a) Ord, Int -> Dictionary a -> ShowS [Dictionary a] -> ShowS Dictionary a -> String (Int -> Dictionary a -> ShowS) -> (Dictionary a -> String) -> ([Dictionary a] -> ShowS) -> Show (Dictionary a) forall a. Show a => Int -> Dictionary a -> ShowS forall a. Show a => [Dictionary a] -> ShowS forall a. Show a => Dictionary a -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Dictionary a] -> ShowS $cshowList :: forall a. Show a => [Dictionary a] -> ShowS show :: Dictionary a -> String $cshow :: forall a. Show a => Dictionary a -> String showsPrec :: Int -> Dictionary a -> ShowS $cshowsPrec :: forall a. Show a => Int -> Dictionary a -> ShowS Show) instance Json.FromJSON a => Json.FromJSON (Dictionary a) where parseJSON :: Value -> Parser (Dictionary a) parseJSON = String -> (Object -> Parser (Dictionary a)) -> Value -> Parser (Dictionary a) forall a. String -> (Object -> Parser a) -> Value -> Parser a Json.withObject String "Dictionary" (\Object o -> do [Text] keys <- Object -> String -> Parser [Text] forall a. FromJSON a => Object -> String -> Parser a get Object o String "keys" Str lastKey <- Object -> String -> Parser Str forall a. FromJSON a => Object -> String -> Parser a get Object o String "last_key" Map Text a value <- Object -> String -> Parser (Map Text a) forall a. FromJSON a => Object -> String -> Parser a get Object o String "value" (Dictionary a -> Text -> Parser (Dictionary a)) -> Dictionary a -> [Text] -> Parser (Dictionary a) forall (t :: * -> *) (m :: * -> *) b a. (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b Monad.foldM (\Dictionary a d Text k -> case Text -> Map Text a -> Maybe a forall k a. Ord k => k -> Map k a -> Maybe a Map.lookup Text k Map Text a value of Maybe a Nothing -> String -> Parser (Dictionary a) forall (m :: * -> *) a. MonadFail m => String -> m a fail ([String] -> String unwords [String "missing key", Text -> String forall a. Show a => a -> String show Text k]) Just a v -> Dictionary a -> Parser (Dictionary a) forall (f :: * -> *) a. Applicative f => a -> f a pure (Str -> a -> Dictionary a -> Dictionary a forall a. Str -> a -> Dictionary a -> Dictionary a DictionaryElement (Text -> Str Str Text k) a v Dictionary a d) ) (Str -> Dictionary a forall a. Str -> Dictionary a DictionaryEnd Str lastKey) ([Text] -> [Text] forall a. [a] -> [a] reverse [Text] keys) ) instance Json.ToJSON a => Json.ToJSON (Dictionary a) where toJSON :: Dictionary a -> Value toJSON Dictionary a d = [Pair] -> Value Json.object [ String -> [Str] -> Pair forall a. ToJSON a => String -> a -> Pair pair String "keys" (Dictionary a -> [Str] forall a. Dictionary a -> [Str] dictionaryKeys Dictionary a d) , String -> Str -> Pair forall a. ToJSON a => String -> a -> Pair pair String "last_key" (Dictionary a -> Str forall a. Dictionary a -> Str dictionaryLastKey Dictionary a d) , String -> Map Text a -> Pair forall a. ToJSON a => String -> a -> Pair pair String "value" (Dictionary a -> Map Text a forall a. Dictionary a -> Map Text a dictionaryValue Dictionary a d) ] dictionaryKeys :: Dictionary a -> [Str] dictionaryKeys :: Dictionary a -> [Str] dictionaryKeys = ((Str, a) -> Str) -> [(Str, a)] -> [Str] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (Str, a) -> Str forall a b. (a, b) -> a fst ([(Str, a)] -> [Str]) -> (Dictionary a -> [(Str, a)]) -> Dictionary a -> [Str] forall b c a. (b -> c) -> (a -> b) -> a -> c . Dictionary a -> [(Str, a)] forall a. Dictionary a -> [(Str, a)] toList dictionaryLastKey :: Dictionary a -> Str dictionaryLastKey :: Dictionary a -> Str dictionaryLastKey Dictionary a x = case Dictionary a x of DictionaryElement Str _ a _ Dictionary a y -> Dictionary a -> Str forall a. Dictionary a -> Str dictionaryLastKey Dictionary a y DictionaryEnd Str y -> Str y dictionaryLookup :: Str -> Dictionary a -> Maybe a dictionaryLookup :: Str -> Dictionary a -> Maybe a dictionaryLookup Str k Dictionary a x = case Dictionary a x of DictionaryElement Str j a v Dictionary a y -> if Str k Str -> Str -> Bool forall a. Eq a => a -> a -> Bool == Str j then a -> Maybe a forall a. a -> Maybe a Just a v else Str -> Dictionary a -> Maybe a forall a. Str -> Dictionary a -> Maybe a dictionaryLookup Str k Dictionary a y DictionaryEnd Str _ -> Maybe a forall a. Maybe a Nothing dictionaryValue :: Dictionary a -> Map Text a dictionaryValue :: Dictionary a -> Map Text a dictionaryValue = (Str -> Text) -> Map Str a -> Map Text a forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a Map.mapKeys Str -> Text strValue (Map Str a -> Map Text a) -> (Dictionary a -> Map Str a) -> Dictionary a -> Map Text a forall b c a. (b -> c) -> (a -> b) -> a -> c . [(Str, a)] -> Map Str a forall k a. Ord k => [(k, a)] -> Map k a Map.fromList ([(Str, a)] -> Map Str a) -> (Dictionary a -> [(Str, a)]) -> Dictionary a -> Map Str a forall b c a. (b -> c) -> (a -> b) -> a -> c . Dictionary a -> [(Str, a)] forall a. Dictionary a -> [(Str, a)] toList get :: Json.FromJSON a => Json.Object -> String -> Json.Parser a get :: Object -> String -> Parser a get Object o String k = Object o Object -> Text -> Parser a forall a. FromJSON a => Object -> Text -> Parser a Json..: String -> Text Text.pack String k pair :: Json.ToJSON a => String -> a -> (Text, Json.Value) pair :: String -> a -> Pair pair String k a v = (String -> Text Text.pack String k, a -> Value forall a. ToJSON a => a -> Value Json.toJSON a v) toList :: Dictionary a -> [(Str, a)] toList :: Dictionary a -> [(Str, a)] toList Dictionary a x = case Dictionary a x of DictionaryElement Str k a v Dictionary a y -> (Str k, a v) (Str, a) -> [(Str, a)] -> [(Str, a)] forall a. a -> [a] -> [a] : Dictionary a -> [(Str, a)] forall a. Dictionary a -> [(Str, a)] toList Dictionary a y DictionaryEnd Str _ -> []