module Data.API.Tools.Enum
( enumTool
, text_enum_nm
, map_enum_nm
) where
import Data.API.TH
import Data.API.Tools.Combinators
import Data.API.Tools.Datatypes
import Data.API.Types
import qualified Data.Text as T
import qualified Data.Map as Map
import Data.Monoid
import Language.Haskell.TH
enumTool :: APITool
enumTool = apiNodeTool $ apiSpecTool mempty mempty mempty enum mempty
where
enum = simpleTool (uncurry gen_se_tx) <> simpleTool (gen_se_mp . fst)
text_enum_nm :: APINode -> Name
text_enum_nm an = mkName $ "_text_" ++ T.unpack (_TypeName $ anName an)
gen_se_tx :: APINode -> SpecEnum -> Q [Dec]
gen_se_tx as se = simpleSigD (text_enum_nm as)
[t| $tc -> T.Text |]
bdy
where
tc = conT $ rep_type_nm as
bdy = lamCaseE [ match (pt fnm) (bd fnm) []
| (fnm,_) <- seAlts se ]
pt fnm = nodeAltConP as fnm []
bd fnm = normalB $ stringE $ T.unpack $ _FieldName fnm
map_enum_nm :: APINode -> Name
map_enum_nm an = mkName $ "_map_" ++ T.unpack (_TypeName $ anName an)
gen_se_mp :: APINode -> Q [Dec]
gen_se_mp as = simpleSigD (map_enum_nm as)
[t| Map.Map T.Text $tc |]
[e| genTextMap $(varE $ text_enum_nm as) |]
where
tc = conT $ rep_type_nm as
genTextMap :: (Ord a,Bounded a,Enum a) => (a->T.Text) -> Map.Map T.Text a
genTextMap f = Map.fromList [ (f x,x) | x<-[minBound..maxBound] ]