-- | Simple value types and functions. module Analyze.Values where import Analyze.Common (Data) import Control.Monad.Catch (Exception, MonadThrow (..)) import Data.Text (Text) import Data.Typeable (Typeable) -- | Singleton type for value types. data ValueType = ValueTypeText | ValueTypeInteger | ValueTypeDouble | ValueTypeBool deriving (Show, Eq, Enum, Bounded) -- | Union type for values. data Value = ValueText Text | ValueInteger Integer | ValueDouble Double | ValueBool Bool deriving (Show, Eq) -- | Returns the type of the value. valueToType :: Value -> ValueType valueToType (ValueText _) = ValueTypeText valueToType (ValueInteger _) = ValueTypeInteger valueToType (ValueDouble _) = ValueTypeDouble valueToType (ValueBool _) = ValueTypeBool -- | Extracts 'Text' from the 'Value'. getText :: Value -> Maybe Text getText (ValueText s) = Just s getText _ = Nothing -- | Extracts 'Integer' from the 'Value'. getInteger :: Value -> Maybe Integer getInteger (ValueInteger i) = Just i getInteger _ = Nothing -- | Extracts 'Double' from the 'Value'. getDouble :: Value -> Maybe Double getDouble (ValueDouble d) = Just d getDouble _ = Nothing -- | Extracts 'Bool' from the 'Value'. getBool :: Value -> Maybe Bool getBool (ValueBool b) = Just b getBool _ = Nothing -- | Exception for when we encounder unexpected values. data ValueTypeError k = ValueTypeError k ValueType Value deriving (Show, Eq, Typeable) instance (Show k, Typeable k) => Exception (ValueTypeError k) -- | Use with 'Analyze.Decoding.requireWhere' to read 'Text' values. textual :: (Data k, MonadThrow m) => k -> Value -> m Text textual _ (ValueText s) = pure s textual k v = throwM (ValueTypeError k ValueTypeText v) -- | Use with 'Analyze.Decoding.requireWhere' to read 'Integer' values. integral :: (Data k, MonadThrow m) => k -> Value -> m Integer integral _ (ValueInteger s) = pure s integral k v = throwM (ValueTypeError k ValueTypeInteger v) -- | Use with 'Analyze.Decoding.requireWhere' to read 'Double' values. floating :: (Data k, MonadThrow m) => k -> Value -> m Double floating _ (ValueDouble s) = pure s floating k v = throwM (ValueTypeError k ValueTypeDouble v) -- | Use with 'Analyze.Decoding.requireWhere' to read 'Bool' values. boolean :: (Data k, MonadThrow m) => k -> Value -> m Bool boolean _ (ValueBool s) = pure s boolean k v = throwM (ValueTypeError k ValueTypeBool v)