module Text.Regex.Pcre2.Foreign.TH where

import Language.Haskell.TH

{-
    For example,
constant ''CInt "ERROR_NOMATCH"
    will produce
foreign import capi unsafe "pcre2.h value PCRE2_ERROR_NOMATCH"
    pcre2_ERROR_NOMATCH :: CInt
-}
constant :: Name -> String -> DecsQ
constant :: Name -> String -> DecsQ
constant Name
typeName String
suffix = [Dec] -> DecsQ
forall (m :: * -> *) a. Monad m => a -> m a
return [Dec
dec] where
    dec :: Dec
dec = Foreign -> Dec
ForeignD (Foreign -> Dec) -> Foreign -> Dec
forall a b. (a -> b) -> a -> b
$ Callconv -> Safety -> String -> Name -> Type -> Foreign
ImportF Callconv
CApi Safety
Unsafe String
str Name
name Type
ty
    str :: String
str = String
"pcre2.h value PCRE2_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
suffix
    name :: Name
name = String -> Name
mkName (String -> Name) -> String -> Name
forall a b. (a -> b) -> a -> b
$ String
"pcre2_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
suffix
    ty :: Type
ty = Name -> Type
ConT Name
typeName

{-
    For example,
getter "callout_block" [t| CUInt |] "version"
    will produce
foreign import capi unsafe "getters.h" pcre2_callout_block_version
    :: Ptr Pcre2_callout_block
    -> IO CUInt
-}
getter :: String -> TypeQ -> String -> DecsQ
getter :: String -> TypeQ -> String -> DecsQ
getter String
blockSuffix TypeQ
fieldTypeQ String
field = do
    Type
fieldType <- TypeQ
fieldTypeQ
    let dec :: Dec
dec = Foreign -> Dec
ForeignD (Foreign -> Dec) -> Foreign -> Dec
forall a b. (a -> b) -> a -> b
$ Callconv -> Safety -> String -> Name -> Type -> Foreign
ImportF Callconv
CApi Safety
Unsafe String
"getters.h" Name
name Type
ty
        name :: Name
name = String -> Name
mkName (String -> Name) -> String -> Name
forall a b. (a -> b) -> a -> b
$ String
"pcre2_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
blockSuffix String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
field
        ty :: Type
ty = Type -> Type -> Type
AppT
            (Type -> Type -> Type
AppT Type
ArrowT (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ Type -> Type -> Type
AppT
                (Name -> Type
ConT (Name -> Type) -> Name -> Type
forall a b. (a -> b) -> a -> b
$ String -> Name
mkName String
"Ptr")
                (Name -> Type
ConT (Name -> Type) -> Name -> Type
forall a b. (a -> b) -> a -> b
$ String -> Name
mkName (String -> Name) -> String -> Name
forall a b. (a -> b) -> a -> b
$ String
"Pcre2_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
blockSuffix))
            (Type -> Type -> Type
AppT
                (Name -> Type
ConT (Name -> Type) -> Name -> Type
forall a b. (a -> b) -> a -> b
$ String -> Name
mkName String
"IO")
                Type
fieldType)
    [Dec] -> DecsQ
forall (m :: * -> *) a. Monad m => a -> m a
return [Dec
dec]