module Bio.MAE.Type
  ( Mae (..)
  , Block (..)
  , Table (..)
  , MaeValue (..)
  , FromMaeValue (..)
  ) where

import           Data.Map.Strict (Map)
import           Data.Maybe      (fromJust)
import           Data.Text       (Text)
import qualified Data.Text       as T (head, null, dropAround)

data Mae = Mae { Mae -> Text
version :: Text
               , Mae -> [Block]
blocks  :: [Block]
               }
  deriving (Mae -> Mae -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Mae -> Mae -> Bool
$c/= :: Mae -> Mae -> Bool
== :: Mae -> Mae -> Bool
$c== :: Mae -> Mae -> Bool
Eq, Int -> Mae -> ShowS
[Mae] -> ShowS
Mae -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Mae] -> ShowS
$cshowList :: [Mae] -> ShowS
show :: Mae -> String
$cshow :: Mae -> String
showsPrec :: Int -> Mae -> ShowS
$cshowsPrec :: Int -> Mae -> ShowS
Show)

data Block = Block { Block -> Text
blockName :: Text
                   , Block -> Map Text MaeValue
fields    :: Map Text MaeValue
                   , Block -> [Table]
tables    :: [Table]
                   }
  deriving (Block -> Block -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Block -> Block -> Bool
$c/= :: Block -> Block -> Bool
== :: Block -> Block -> Bool
$c== :: Block -> Block -> Bool
Eq, Int -> Block -> ShowS
[Block] -> ShowS
Block -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Block] -> ShowS
$cshowList :: [Block] -> ShowS
show :: Block -> String
$cshow :: Block -> String
showsPrec :: Int -> Block -> ShowS
$cshowsPrec :: Int -> Block -> ShowS
Show)

data Table = Table { Table -> Text
tableName :: Text
                   , Table -> Map Text [MaeValue]
contents  :: Map Text [MaeValue]
                   }
  deriving (Table -> Table -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Table -> Table -> Bool
$c/= :: Table -> Table -> Bool
== :: Table -> Table -> Bool
$c== :: Table -> Table -> Bool
Eq, Int -> Table -> ShowS
[Table] -> ShowS
Table -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Table] -> ShowS
$cshowList :: [Table] -> ShowS
show :: Table -> String
$cshow :: Table -> String
showsPrec :: Int -> Table -> ShowS
$cshowsPrec :: Int -> Table -> ShowS
Show)                   

data MaeValue = IntMaeValue Int
              | RealMaeValue Float
              | StringMaeValue Text
              | BoolMaeValue Bool
              | Absent
  deriving (MaeValue -> MaeValue -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MaeValue -> MaeValue -> Bool
$c/= :: MaeValue -> MaeValue -> Bool
== :: MaeValue -> MaeValue -> Bool
$c== :: MaeValue -> MaeValue -> Bool
Eq, Int -> MaeValue -> ShowS
[MaeValue] -> ShowS
MaeValue -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MaeValue] -> ShowS
$cshowList :: [MaeValue] -> ShowS
show :: MaeValue -> String
$cshow :: MaeValue -> String
showsPrec :: Int -> MaeValue -> ShowS
$cshowsPrec :: Int -> MaeValue -> ShowS
Show)

class FromMaeValue a where
    fromMaeValue :: MaeValue -> Maybe a

    unsafeFromMaeValue :: MaeValue -> a
    unsafeFromMaeValue = forall a. HasCallStack => Maybe a -> a
fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromMaeValue a => MaeValue -> Maybe a
fromMaeValue

instance FromMaeValue Int where
    fromMaeValue :: MaeValue -> Maybe Int
    fromMaeValue :: MaeValue -> Maybe Int
fromMaeValue (IntMaeValue Int
i) = forall a. a -> Maybe a
Just Int
i
    fromMaeValue MaeValue
_               = forall a. Maybe a
Nothing

instance FromMaeValue Float where
    fromMaeValue :: MaeValue -> Maybe Float
    fromMaeValue :: MaeValue -> Maybe Float
fromMaeValue (RealMaeValue Float
f) = forall a. a -> Maybe a
Just Float
f
    fromMaeValue MaeValue
_                = forall a. Maybe a
Nothing

instance FromMaeValue Bool where
    fromMaeValue :: MaeValue -> Maybe Bool
    fromMaeValue :: MaeValue -> Maybe Bool
fromMaeValue (BoolMaeValue Bool
b) = forall a. a -> Maybe a
Just Bool
b
    fromMaeValue MaeValue
_                = forall a. Maybe a
Nothing

instance FromMaeValue Text where
    fromMaeValue :: MaeValue -> Maybe Text
    fromMaeValue :: MaeValue -> Maybe Text
fromMaeValue (StringMaeValue Text
t) = forall a. a -> Maybe a
Just Text
t
    fromMaeValue MaeValue
_                  = forall a. Maybe a
Nothing

instance FromMaeValue Char where
    fromMaeValue :: MaeValue -> Maybe Char
    fromMaeValue :: MaeValue -> Maybe Char
fromMaeValue (StringMaeValue Text
t) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ if Text -> Bool
T.null Text
t then Char
' ' else Text -> Char
T.head forall a b. (a -> b) -> a -> b
$ Text -> Text
stripQuotes Text
t
    fromMaeValue MaeValue
_                  = forall a. Maybe a
Nothing
         
stripQuotes :: Text -> Text
stripQuotes :: Text -> Text
stripQuotes = (Char -> Bool) -> Text -> Text
T.dropAround (forall a. Eq a => a -> a -> Bool
== Char
'"')