{-# LANGUAGE QuasiQuotes #-}
module Helper (genForEnum, genForStruct, mkName, castForeignPtr, newIORef, Connector, fromGI, toGI) where
import Data.Char
import Data.GI.Base.BasicTypes
import Data.IORef
import Foreign.ForeignPtr
import GI.Cairo.Connector
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
genForEnum :: Name -> Q [Dec]
genForEnum enumName =
let n = capital2underscore $ unOccName $ nameOccName enumName
c_fun = "cairo_gobject_" ++ n ++ "_get_type"
fun = mkName $ n ++ "GType"
in sequence
[ return $ ForeignD $ ImportF CCall Safe c_fun fun $ AppT (ConT $ mkName "IO") (ConT $ mkName "GType")
, head <$> [d|instance BoxedEnum $(conT enumName) where
boxedEnumType _ = $(varE fun)|] ]
genForStruct :: Name -> Q [Dec]
genForStruct structName =
let n = capital2underscore $ unOccName $ nameOccName structName
c_fun = "cairo_gobject_" ++ n ++ "_get_type"
fun = mkName $ n ++ "GType"
qn = Name (nameOccName structName) (NameQ $ ModName "T")
in sequence
[ newtypeD (cxt []) structName [] Nothing (normalC structName [bangType (bang noSourceUnpackedness noSourceStrictness) $ appT (conT ''ManagedPtr) (conT structName)]) []
, head <$> [d|instance BoxedObject $(conT structName) where
boxedType _ = $(varE fun)|]
, return $ ForeignD $ ImportF CCall Safe c_fun fun $ AppT (ConT $ mkName "IO") (ConT $ mkName "GType")
, head <$> [d|instance Connector $(conT structName) $(conT qn) where
fromGI $(conP structName [conP (mkName "ManagedPtr") [varP $ mkName "fp", wildP, wildP]]) = return $ $(conE qn) $ castForeignPtr $(varE $ mkName "fp")
toGI $(conP qn [varP (mkName "fp")]) = newIORef Nothing >>= return . $(conE structName) . ManagedPtr (castForeignPtr $(varE $ mkName "fp")) Nothing|] ]
capital2underscore :: String -> String
capital2underscore i = case concatMap (\c ->
if isUpper c
then ['_', toLower c]
else [c]) i of
'_' : x -> x
x -> x
nameOccName :: Name -> OccName
nameOccName (Name occName _) = occName
unOccName :: OccName -> String
unOccName (OccName s) = s