{-# LANGUAGE ExistentialQuantification, TypeFamilies, FlexibleContexts, OverloadedStrings, CPP #-}
module Data.Text.Format.Heavy.Types where
import Data.Default
#if MIN_VERSION_base(4,9,0)
import Data.Monoid (Monoid)
import Data.Semigroup ((<>))
import qualified Data.Semigroup as Semigroup
#else
import Data.Monoid
#endif
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as B
type VarName = TL.Text
type VarFormat = Maybe TL.Text
data FormatItem =
FString TL.Text
| FVariable {
vName :: VarName
, vFormat :: VarFormat
}
deriving (Eq)
instance Show FormatItem where
show (FString text) = TL.unpack text
show (FVariable name Nothing) = TL.unpack $ "{" <> name <> "}"
show (FVariable name (Just fmt)) = TL.unpack $ "{" <> name <> ":" <> fmt <> "}"
data Format = Format [FormatItem]
deriving (Eq)
instance Show Format where
show (Format lst) = concat $ map show lst
appendFormat :: Format -> Format -> Format
appendFormat (Format xs) (Format ys) = Format (xs ++ ys)
#if MIN_VERSION_base(4,9,0)
instance Semigroup.Semigroup Format where
(<>) = appendFormat
#endif
instance Monoid Format where
mempty = Format []
#if MIN_VERSION_base(4,11,0)
#elif MIN_VERSION_base(4,9,0)
mappend = (Semigroup.<>)
#else
mappend = appendFormat
#endif
class (Default f, Show f) => IsVarFormat f where
parseVarFormat :: TL.Text -> Either String f
instance IsVarFormat () where
parseVarFormat "" = Right ()
parseVarFormat fmt = Left $ "Unsupported format: " ++ TL.unpack fmt
class Formatable a where
formatVar :: VarFormat
-> a
-> Either String B.Builder
data Variable = forall a. Formatable a => Variable a
instance Show Variable where
show (Variable v) = either error toString $ formatVar Nothing v
where
toString :: B.Builder -> String
toString b = TL.unpack $ B.toLazyText b
instance Formatable Variable where
formatVar fmt (Variable x) = formatVar fmt x
formatAnyVar :: VarFormat -> Variable -> Either String B.Builder
formatAnyVar fmt (Variable v) = formatVar fmt v
class VarContainer c where
lookupVar :: VarName -> c -> Maybe Variable
class VarContainer c => ClosedVarContainer c where
allVarNames :: c -> [VarName]