{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
module Toml.Type.AnyValue
( AnyValue (..)
, reifyAnyValues
, liftMatch
, matchBool
, matchInteger
, matchDouble
, matchText
, matchDate
, matchArray
) where
import Data.Text (Text)
import Data.Type.Equality ((:~:) (..))
import Toml.Type.Value (DateTime, TValue, TypeMismatchError, Value (..), eqValueList, sameValue)
data AnyValue = forall (t :: TValue) . AnyValue (Value t)
instance Show AnyValue where
show (AnyValue v) = show v
instance Eq AnyValue where
(AnyValue (Bool b1)) == (AnyValue (Bool b2)) = b1 == b2
(AnyValue (Integer i1)) == (AnyValue (Integer i2)) = i1 == i2
(AnyValue (Double f1)) == (AnyValue (Double f2)) = f1 == f2
(AnyValue (Text s1)) == (AnyValue (Text s2)) = s1 == s2
(AnyValue (Date d1)) == (AnyValue (Date d2)) = d1 == d2
(AnyValue (Array a1)) == (AnyValue (Array a2)) = eqValueList a1 a2
_ == _ = False
matchBool :: Value t -> Maybe Bool
matchBool (Bool b) = Just b
matchBool _ = Nothing
matchInteger :: Value t -> Maybe Integer
matchInteger (Integer n) = Just n
matchInteger _ = Nothing
matchDouble :: Value t -> Maybe Double
matchDouble (Double f) = Just f
matchDouble _ = Nothing
matchText :: Value t -> Maybe Text
matchText (Text s) = Just s
matchText _ = Nothing
matchDate :: Value t -> Maybe DateTime
matchDate (Date d) = Just d
matchDate _ = Nothing
matchArray :: (AnyValue -> Maybe a) -> Value t -> Maybe [a]
matchArray matchValue (Array a) = mapM (liftMatch matchValue) a
matchArray _ _ = Nothing
liftMatch :: (AnyValue -> Maybe a) -> (Value t -> Maybe a)
liftMatch fromAnyValue = fromAnyValue . AnyValue
reifyAnyValues :: Value t -> [AnyValue] -> Either TypeMismatchError [Value t]
reifyAnyValues _ [] = Right []
reifyAnyValues v (AnyValue av : xs) = sameValue v av >>= \Refl -> (av :) <$> reifyAnyValues v xs