{-# LANGUAGE DefaultSignatures, FlexibleInstances, TypeSynonymInstances #-}
{-# LANGUAGE TupleSections #-}
module Data.Tini.IniValue where
import Control.Applicative ((<|>))
import Data.Char (toLower)
import Data.Int
import Data.List (intercalate)
import Data.Word
import Data.Tini.Utils (trim, splitOn)
class IniValue a where
showValue :: a -> String
default showValue :: Show a => a -> String
showValue = show
readValue :: String -> Maybe a
default readValue :: Read a => String -> Maybe a
readValue s =
case reads s of
[(x, "")] -> Just x
_ -> Nothing
instance IniValue Int
instance IniValue Int8
instance IniValue Int16
instance IniValue Int32
instance IniValue Int64
instance IniValue Word
instance IniValue Word8
instance IniValue Word16
instance IniValue Word32
instance IniValue Word64
instance IniValue Integer
instance IniValue Float
instance IniValue Double
instance IniValue Char where
showValue c = [c]
readValue [c] = Just c
readValue _ = Nothing
instance IniValue Bool where
showValue True = "true"
showValue False = "false"
readValue s
| s' `elem` ["true", "yes", "t", "y", "1", "on"] = Just True
| s' `elem` ["false", "no", "f", "n", "0", "off"] = Just False
| otherwise = Nothing
where s' = map toLower s
instance {-# OVERLAPPING #-} IniValue String where
showValue = id
readValue = Just
instance IniValue a => IniValue [a] where
showValue = intercalate "," . map showValue
readValue = sequence . map readValue . map trim . splitOn ','
instance IniValue a => IniValue (Maybe a) where
showValue = maybe "" showValue
readValue "" = Just Nothing
readValue x = Just $ readValue x
instance (IniValue a, IniValue b) => IniValue (Either a b) where
showValue = either showValue showValue
readValue s = (Left <$> readValue s) <|> (Right <$> readValue s)
instance (IniValue a, IniValue b) => IniValue (a, b) where
showValue (a, b) = showValue [showValue a, showValue b]
readValue s = do
[a, b] <- readValue s
(,) <$> readValue a <*> readValue b
instance (IniValue a, IniValue b, IniValue c) => IniValue (a, b, c) where
showValue (a, b, c) = showValue [showValue a, showValue b, showValue c]
readValue s = do
Just [a, b, c] <- readValue s
(,,) <$> readValue a <*> readValue b <*> readValue c