{-# LANGUAGE OverloadedStrings #-}
module HsLua.Packaging.Module
(
Module (..)
, ModuleDoc (..)
, Field (..)
, defmodule
, withFields
, withFunctions
, withOperations
, associateType
, renameTo
, deffield
, withType
, withDescription
, withValue
, HasName (..)
, HasDescription (..)
, registerModule
, preloadModule
, preloadModuleWithName
, pushModule
, Operation (..)
)
where
import Control.Monad (forM_)
import Data.Text (Text)
import HsLua.Core
import HsLua.Marshalling (pushName)
import HsLua.ObjectOrientation.Operation (Operation (..), metamethodName)
import HsLua.Packaging.Documentation
import HsLua.Packaging.Types
import HsLua.Packaging.UDType (initType)
import HsLua.Typing (TypeSpec, anyType)
import qualified HsLua.Core.Utf8 as Utf8
import qualified HsLua.Packaging.Function as Fun
defmodule :: Name -> Module e
defmodule :: forall e. Name -> Module e
defmodule Name
name = Module
{ moduleName :: Name
moduleName = Name
name
, moduleDescription :: Text
moduleDescription = Text
forall a. Monoid a => a
mempty
, moduleFields :: [Field e]
moduleFields = [Field e]
forall a. Monoid a => a
mempty
, moduleFunctions :: [DocumentedFunction e]
moduleFunctions = [DocumentedFunction e]
forall a. Monoid a => a
mempty
, moduleOperations :: [(Operation, DocumentedFunction e)]
moduleOperations = [(Operation, DocumentedFunction e)]
forall a. Monoid a => a
mempty
, moduleTypeDocs :: [TypeDoc]
moduleTypeDocs = [TypeDoc]
forall a. Monoid a => a
mempty
, moduleTypeInitializers :: [LuaE e Name]
moduleTypeInitializers = [LuaE e Name]
forall a. Monoid a => a
mempty
}
withFields :: Module e -> [Field e] -> Module e
withFields :: forall e. Module e -> [Field e] -> Module e
withFields Module e
mdl [Field e]
fields = Module e
mdl { moduleFields = fields }
withFunctions :: Module e -> [DocumentedFunction e] -> Module e
withFunctions :: forall e. Module e -> [DocumentedFunction e] -> Module e
withFunctions Module e
mdl [DocumentedFunction e]
fns =
let addPrefix :: DocumentedFunction e -> DocumentedFunction e
addPrefix DocumentedFunction e
fn =
let doc :: FunctionDoc
doc = DocumentedFunction e -> FunctionDoc
forall e. DocumentedFunction e -> FunctionDoc
functionDoc DocumentedFunction e
fn
prefixed :: Text
prefixed = ByteString -> Text
Utf8.toText (Name -> ByteString
fromName (Name -> ByteString) -> Name -> ByteString
forall a b. (a -> b) -> a -> b
$ Module e -> Name
forall a. HasName a => a -> Name
getName Module e
mdl) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
FunctionDoc -> Text
funDocName FunctionDoc
doc
in DocumentedFunction e
fn { functionDoc = doc { funDocName = prefixed } }
in Module e
mdl { moduleFunctions = map addPrefix fns }
withOperations :: Module e -> [(Operation, DocumentedFunction e)] -> Module e
withOperations :: forall e.
Module e -> [(Operation, DocumentedFunction e)] -> Module e
withOperations Module e
mdl [(Operation, DocumentedFunction e)]
ops = Module e
mdl { moduleOperations = ops }
withDescription :: HasDescription a => a -> Text -> a
withDescription :: forall a. HasDescription a => a -> Text -> a
withDescription = a -> Text -> a
forall a. HasDescription a => a -> Text -> a
setDescription
associateType :: LuaError e => Module e -> DocumentedType e a -> Module e
associateType :: forall e a.
LuaError e =>
Module e -> DocumentedType e a -> Module e
associateType Module e
mdl DocumentedType e a
tp = Module e
mdl
{ moduleTypeInitializers = initType tp : moduleTypeInitializers mdl
, moduleTypeDocs = generateTypeDocumentation tp : moduleTypeDocs mdl
}
renameTo :: HasName a => a -> Name -> a
renameTo :: forall a. HasName a => a -> Name -> a
renameTo = a -> Name -> a
forall a. HasName a => a -> Name -> a
setName
infixl 0 `withFields`, `withFunctions`, `withDescription`, `withOperations`
infixl 0 `associateType`
deffield :: Name -> Field e
deffield :: forall e. Name -> Field e
deffield Name
name = Field
{ fieldName :: Name
fieldName = Name
name
, fieldPushValue :: LuaE e ()
fieldPushValue = () -> LuaE e ()
forall a. a -> LuaE e a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
, fieldDoc :: FieldDoc
fieldDoc = FieldDoc
{ fieldDocName :: Text
fieldDocName = ByteString -> Text
Utf8.toText (ByteString -> Text) -> ByteString -> Text
forall a b. (a -> b) -> a -> b
$ Name -> ByteString
fromName Name
name
, fieldDocType :: TypeSpec
fieldDocType = TypeSpec
anyType
, fieldDocDescription :: Text
fieldDocDescription = Text
forall a. Monoid a => a
mempty
}
}
withType :: Field e -> TypeSpec -> Field e
withType :: forall e. Field e -> TypeSpec -> Field e
withType Field e
fld TypeSpec
typespec =
let doc :: FieldDoc
doc = Field e -> FieldDoc
forall e. Field e -> FieldDoc
fieldDoc Field e
fld
in Field e
fld { fieldDoc = doc { fieldDocType = typespec }}
withValue :: Field e -> LuaE e () -> Field e
withValue :: forall e. Field e -> LuaE e () -> Field e
withValue Field e
fld LuaE e ()
pusher = Field e
fld { fieldPushValue = pusher }
infixl 0 `withType`, `withValue`
create :: LuaE e ()
create :: forall e. LuaE e ()
create = LuaE e ()
forall e. LuaE e ()
newtable
registerModule :: LuaError e => Module e -> LuaE e ()
registerModule :: forall e. LuaError e => Module e -> LuaE e ()
registerModule Module e
mdl =
Name -> (Name -> LuaE e ()) -> LuaE e ()
forall e. LuaError e => Name -> (Name -> LuaE e ()) -> LuaE e ()
requirehs (Module e -> Name
forall e. Module e -> Name
moduleName Module e
mdl) (LuaE e () -> Name -> LuaE e ()
forall a b. a -> b -> a
const (Module e -> LuaE e ()
forall e. LuaError e => Module e -> LuaE e ()
pushModule Module e
mdl))
preloadModuleWithName :: LuaError e => Module e -> Name -> LuaE e ()
preloadModuleWithName :: forall e. LuaError e => Module e -> Name -> LuaE e ()
preloadModuleWithName Module e
documentedModule Name
name = Module e -> LuaE e ()
forall e. LuaError e => Module e -> LuaE e ()
preloadModule (Module e -> LuaE e ()) -> Module e -> LuaE e ()
forall a b. (a -> b) -> a -> b
$
Module e
documentedModule { moduleName = name }
preloadModule :: LuaError e => Module e -> LuaE e ()
preloadModule :: forall e. LuaError e => Module e -> LuaE e ()
preloadModule Module e
mdl =
Name -> LuaE e NumResults -> LuaE e ()
forall e. LuaError e => Name -> LuaE e NumResults -> LuaE e ()
preloadhs (Module e -> Name
forall e. Module e -> Name
moduleName Module e
mdl) (LuaE e NumResults -> LuaE e ()) -> LuaE e NumResults -> LuaE e ()
forall a b. (a -> b) -> a -> b
$ do
Module e -> LuaE e ()
forall e. LuaError e => Module e -> LuaE e ()
pushModule Module e
mdl
NumResults -> LuaE e NumResults
forall a. a -> LuaE e a
forall (m :: * -> *) a. Monad m => a -> m a
return (CInt -> NumResults
NumResults CInt
1)
pushModule :: LuaError e => Module e -> LuaE e ()
pushModule :: forall e. LuaError e => Module e -> LuaE e ()
pushModule Module e
mdl = do
Int -> String -> LuaE e ()
forall e. LuaError e => Int -> String -> LuaE e ()
checkstack' Int
10 String
"pushModule"
LuaE e ()
forall e. LuaE e ()
create
Pusher e ModuleDoc
forall e. LuaError e => Pusher e ModuleDoc
pushModuleDoc (Module e -> ModuleDoc
forall e. Module e -> ModuleDoc
generateModuleDocumentation Module e
mdl)
StackIndex -> LuaE e ()
forall e. LuaError e => StackIndex -> LuaE e ()
registerDocumentation (CInt -> StackIndex
nth CInt
2)
[DocumentedFunction e]
-> (DocumentedFunction e -> LuaE e ()) -> LuaE e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Module e -> [DocumentedFunction e]
forall e. Module e -> [DocumentedFunction e]
moduleFunctions Module e
mdl) ((DocumentedFunction e -> LuaE e ()) -> LuaE e ())
-> (DocumentedFunction e -> LuaE e ()) -> LuaE e ()
forall a b. (a -> b) -> a -> b
$ \DocumentedFunction e
fn -> do
Name -> LuaE e ()
forall e. Name -> LuaE e ()
pushName (DocumentedFunction e -> Name
forall e. DocumentedFunction e -> Name
functionName DocumentedFunction e
fn)
DocumentedFunction e -> LuaE e ()
forall e. LuaError e => DocumentedFunction e -> LuaE e ()
Fun.pushDocumentedFunction DocumentedFunction e
fn
StackIndex -> LuaE e ()
forall e. LuaError e => StackIndex -> LuaE e ()
rawset (CInt -> StackIndex
nth CInt
3)
[Field e] -> (Field e -> LuaE e ()) -> LuaE e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Module e -> [Field e]
forall e. Module e -> [Field e]
moduleFields Module e
mdl) ((Field e -> LuaE e ()) -> LuaE e ())
-> (Field e -> LuaE e ()) -> LuaE e ()
forall a b. (a -> b) -> a -> b
$ \Field e
fld -> do
Name -> LuaE e ()
forall e. Name -> LuaE e ()
pushName (Field e -> Name
forall e. Field e -> Name
fieldName Field e
fld)
Field e -> LuaE e ()
forall e. Field e -> LuaE e ()
fieldPushValue Field e
fld
StackIndex -> LuaE e ()
forall e. LuaError e => StackIndex -> LuaE e ()
rawset (CInt -> StackIndex
nth CInt
3)
case Module e -> [(Operation, DocumentedFunction e)]
forall e. Module e -> [(Operation, DocumentedFunction e)]
moduleOperations Module e
mdl of
[] -> () -> LuaE e ()
forall a. a -> LuaE e a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
[(Operation, DocumentedFunction e)]
ops -> do
LuaE e ()
forall e. LuaE e ()
newtable
[(Operation, DocumentedFunction e)]
-> ((Operation, DocumentedFunction e) -> LuaE e ()) -> LuaE e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(Operation, DocumentedFunction e)]
ops (((Operation, DocumentedFunction e) -> LuaE e ()) -> LuaE e ())
-> ((Operation, DocumentedFunction e) -> LuaE e ()) -> LuaE e ()
forall a b. (a -> b) -> a -> b
$ \(Operation
op, DocumentedFunction e
fn) -> do
Name -> LuaE e ()
forall e. Name -> LuaE e ()
pushName (Name -> LuaE e ()) -> Name -> LuaE e ()
forall a b. (a -> b) -> a -> b
$ Operation -> Name
metamethodName Operation
op
DocumentedFunction e -> LuaE e ()
forall e. LuaError e => DocumentedFunction e -> LuaE e ()
Fun.pushDocumentedFunction (DocumentedFunction e -> LuaE e ())
-> DocumentedFunction e -> LuaE e ()
forall a b. (a -> b) -> a -> b
$ DocumentedFunction e
fn DocumentedFunction e -> Name -> DocumentedFunction e
forall a. HasName a => a -> Name -> a
`setName` Name
""
StackIndex -> LuaE e ()
forall e. LuaError e => StackIndex -> LuaE e ()
rawset (CInt -> StackIndex
nth CInt
3)
StackIndex -> LuaE e ()
forall e. StackIndex -> LuaE e ()
setmetatable (CInt -> StackIndex
nth CInt
2)