{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE CPP #-}
module System.Win32.Error.TH
( genErrCode
, gentoDWORD
, genfromDWORD
) where
import Language.Haskell.TH
import System.Win32 (DWORD)
import System.Win32.Error.Mapping
errCode :: Name
errCode = mkName "ErrCode"
errOther :: Name
errOther = mkName "Other"
genErrCode :: Q [Dec]
#if MIN_VERSION_template_haskell(2,12,0)
genErrCode = return [DataD [] errCode [] Nothing cons [(DerivClause Nothing $ map ConT [''Eq, ''Show])]]
#elif MIN_VERSION_template_haskell(2,11,0)
genErrCode = return [DataD [] errCode [] Nothing cons (map ConT [''Eq, ''Show])]
#else
genErrCode = return [DataD [] errCode [] cons [''Eq, ''Show]]
#endif
where
con name = NormalC name []
#if __GLASGOW_HASKELL__ < 800
cons = map (con . snd) mapping ++ [NormalC errOther [(IsStrict, ConT ''DWORD)]]
#else
cons = map (con . snd) mapping ++ [NormalC errOther [(Bang NoSourceUnpackedness SourceStrict, ConT ''DWORD)]]
#endif
gentoDWORD :: Q [Dec]
gentoDWORD = do
x <- newName "x"
return [ SigD toDWORD (AppT (AppT ArrowT (ConT errCode)) (ConT ''DWORD))
, FunD toDWORD $ Clause [ConP errOther [VarP x]] (NormalB (VarE x)) [] : map genClause mapping
]
where
toDWORD = mkName "toDWORD"
genClause :: (DWORD, Name) -> Clause
genClause (dw, err) = Clause [ConP err []] (NormalB (LitE . litDWORD $ dw)) []
genfromDWORD :: Q [Dec]
genfromDWORD = do
x <- newName "x"
return [ SigD fromDWORD (AppT (AppT ArrowT (ConT ''DWORD)) (ConT errCode))
, FunD fromDWORD $ map genClause mapping ++ [Clause [VarP x] (NormalB (AppE (ConE errOther) (VarE x))) []]
]
where
fromDWORD = mkName "fromDWORD"
genClause :: (DWORD, Name) -> Clause
genClause (dw, err) = Clause [LitP $ litDWORD dw] (NormalB (ConE err)) []
litDWORD :: DWORD -> Lit
litDWORD = IntegerL . toInteger