    {-|
    Module      : HsLua.Packaging.Types
    Copyright   : © 2020-2024 Albert Krewinkel
    License     : MIT
    Maintainer  : Albert Krewinkel <tarleb@hslua.org>
    Stability   : alpha
    Portability : Portable

    Marshaling and documenting Haskell functions.
    -}
    module HsLua.Packaging.Types
      ( -- * Documented module
        Module (..)
      , Field (..)
        -- * Documented functions
      , DocumentedFunction (..)
        -- ** Documentation types
      , FunctionDoc (..)
      , ParameterDoc (..)
      , ResultsDoc (..)
      , ResultValueDoc (..)
      ) where

    import Data.Text (Text)
    import Data.Version (Version)
    import HsLua.Core (LuaE, Name, NumResults)
    import HsLua.ObjectOrientation (Operation)
    import HsLua.Typing (TypeSpec)

    -- | Named and documented Lua module.
    data Module e = Module
      { forall e. Module e -> Name
    moduleName :: Name
      , forall e. Module e -> Text
    moduleDescription :: Text
      , forall e. Module e -> [Field e]
    moduleFields :: [Field e]
      , forall e. Module e -> [DocumentedFunction e]
    moduleFunctions :: [DocumentedFunction e]
      , forall e. Module e -> [(Operation, DocumentedFunction e)]
    moduleOperations :: [(Operation, DocumentedFunction e)]
      , forall e. Module e -> [LuaE e Name]
    moduleTypeInitializers :: [LuaE e Name]
      }

    -- | Self-documenting module field
    data Field e = Field
      { forall e. Field e -> Text
    fieldName :: Text
      , forall e. Field e -> TypeSpec
    fieldType :: TypeSpec
      , forall e. Field e -> Text
    fieldDescription :: Text
      , forall e. Field e -> LuaE e ()
    fieldPushValue :: LuaE e ()
      }

    --
    -- Function components
    --

    -- | Haskell equivallent to CFunction, i.e., function callable
    -- from Lua.
    data DocumentedFunction e = DocumentedFunction
      { forall e. DocumentedFunction e -> LuaE e NumResults
    callFunction :: LuaE e NumResults
      , forall e. DocumentedFunction e -> Name
    functionName :: Name
      , forall e. DocumentedFunction e -> FunctionDoc
    functionDoc  :: FunctionDoc
      }

    --
    -- Documentation types
    --

    -- | Documentation for a Haskell function
    data FunctionDoc = FunctionDoc
      { FunctionDoc -> Text
    functionDescription :: Text
      , FunctionDoc -> [ParameterDoc]
    parameterDocs       :: [ParameterDoc]
      , FunctionDoc -> ResultsDoc
    functionResultsDocs :: ResultsDoc
      , FunctionDoc -> Maybe Version
    functionSince       :: Maybe Version  -- ^ Version in which the function
                                              -- was introduced.
      }
      deriving (FunctionDoc -> FunctionDoc -> Bool
    (FunctionDoc -> FunctionDoc -> Bool)
    -> (FunctionDoc -> FunctionDoc -> Bool) -> Eq FunctionDoc
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: FunctionDoc -> FunctionDoc -> Bool
    == :: FunctionDoc -> FunctionDoc -> Bool
    $c/= :: FunctionDoc -> FunctionDoc -> Bool
    /= :: FunctionDoc -> FunctionDoc -> Bool
    Eq, Eq FunctionDoc
    Eq FunctionDoc =>
    (FunctionDoc -> FunctionDoc -> Ordering)
    -> (FunctionDoc -> FunctionDoc -> Bool)
    -> (FunctionDoc -> FunctionDoc -> Bool)
    -> (FunctionDoc -> FunctionDoc -> Bool)
    -> (FunctionDoc -> FunctionDoc -> Bool)
    -> (FunctionDoc -> FunctionDoc -> FunctionDoc)
    -> (FunctionDoc -> FunctionDoc -> FunctionDoc)
    -> Ord FunctionDoc
    FunctionDoc -> FunctionDoc -> Bool
    FunctionDoc -> FunctionDoc -> Ordering
    FunctionDoc -> FunctionDoc -> FunctionDoc
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: FunctionDoc -> FunctionDoc -> Ordering
    compare :: FunctionDoc -> FunctionDoc -> Ordering
    $c< :: FunctionDoc -> FunctionDoc -> Bool
    < :: FunctionDoc -> FunctionDoc -> Bool
    $c<= :: FunctionDoc -> FunctionDoc -> Bool
    <= :: FunctionDoc -> FunctionDoc -> Bool
    $c> :: FunctionDoc -> FunctionDoc -> Bool
    > :: FunctionDoc -> FunctionDoc -> Bool
    $c>= :: FunctionDoc -> FunctionDoc -> Bool
    >= :: FunctionDoc -> FunctionDoc -> Bool
    $cmax :: FunctionDoc -> FunctionDoc -> FunctionDoc
    max :: FunctionDoc -> FunctionDoc -> FunctionDoc
    $cmin :: FunctionDoc -> FunctionDoc -> FunctionDoc
    min :: FunctionDoc -> FunctionDoc -> FunctionDoc
    Ord, Int -> FunctionDoc -> ShowS
    [FunctionDoc] -> ShowS
    FunctionDoc -> String
    (Int -> FunctionDoc -> ShowS)
    -> (FunctionDoc -> String)
    -> ([FunctionDoc] -> ShowS)
    -> Show FunctionDoc
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> FunctionDoc -> ShowS
    showsPrec :: Int -> FunctionDoc -> ShowS
    $cshow :: FunctionDoc -> String
    show :: FunctionDoc -> String
    $cshowList :: [FunctionDoc] -> ShowS
    showList :: [FunctionDoc] -> ShowS
    Show)

    -- | Documentation for function parameters.
    data ParameterDoc = ParameterDoc
      { ParameterDoc -> Text
    parameterName :: Text
      , ParameterDoc -> TypeSpec
    parameterType :: TypeSpec
      , ParameterDoc -> Text
    parameterDescription :: Text
      , ParameterDoc -> Bool
    parameterIsOptional :: Bool
      }
      deriving (ParameterDoc -> ParameterDoc -> Bool
    (ParameterDoc -> ParameterDoc -> Bool)
    -> (ParameterDoc -> ParameterDoc -> Bool) -> Eq ParameterDoc
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ParameterDoc -> ParameterDoc -> Bool
    == :: ParameterDoc -> ParameterDoc -> Bool
    $c/= :: ParameterDoc -> ParameterDoc -> Bool
    /= :: ParameterDoc -> ParameterDoc -> Bool
    Eq, Eq ParameterDoc
    Eq ParameterDoc =>
    (ParameterDoc -> ParameterDoc -> Ordering)
    -> (ParameterDoc -> ParameterDoc -> Bool)
    -> (ParameterDoc -> ParameterDoc -> Bool)
    -> (ParameterDoc -> ParameterDoc -> Bool)
    -> (ParameterDoc -> ParameterDoc -> Bool)
    -> (ParameterDoc -> ParameterDoc -> ParameterDoc)
    -> (ParameterDoc -> ParameterDoc -> ParameterDoc)
    -> Ord ParameterDoc
    ParameterDoc -> ParameterDoc -> Bool
    ParameterDoc -> ParameterDoc -> Ordering
    ParameterDoc -> ParameterDoc -> ParameterDoc
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ParameterDoc -> ParameterDoc -> Ordering
    compare :: ParameterDoc -> ParameterDoc -> Ordering
    $c< :: ParameterDoc -> ParameterDoc -> Bool
    < :: ParameterDoc -> ParameterDoc -> Bool
    $c<= :: ParameterDoc -> ParameterDoc -> Bool
    <= :: ParameterDoc -> ParameterDoc -> Bool
    $c> :: ParameterDoc -> ParameterDoc -> Bool
    > :: ParameterDoc -> ParameterDoc -> Bool
    $c>= :: ParameterDoc -> ParameterDoc -> Bool
    >= :: ParameterDoc -> ParameterDoc -> Bool
    $cmax :: ParameterDoc -> ParameterDoc -> ParameterDoc
    max :: ParameterDoc -> ParameterDoc -> ParameterDoc
    $cmin :: ParameterDoc -> ParameterDoc -> ParameterDoc
    min :: ParameterDoc -> ParameterDoc -> ParameterDoc
    Ord, Int -> ParameterDoc -> ShowS
    [ParameterDoc] -> ShowS
    ParameterDoc -> String
    (Int -> ParameterDoc -> ShowS)
    -> (ParameterDoc -> String)
    -> ([ParameterDoc] -> ShowS)
    -> Show ParameterDoc
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ParameterDoc -> ShowS
    showsPrec :: Int -> ParameterDoc -> ShowS
    $cshow :: ParameterDoc -> String
    show :: ParameterDoc -> String
    $cshowList :: [ParameterDoc] -> ShowS
    showList :: [ParameterDoc] -> ShowS
    Show)

    -- | Documentation for the return values of a function.
    data ResultsDoc
      = ResultsDocList [ResultValueDoc]  -- ^ List of individual results
      | ResultsDocMult Text              -- ^ Flexible results
      deriving (ResultsDoc -> ResultsDoc -> Bool
    (ResultsDoc -> ResultsDoc -> Bool)
    -> (ResultsDoc -> ResultsDoc -> Bool) -> Eq ResultsDoc
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ResultsDoc -> ResultsDoc -> Bool
    == :: ResultsDoc -> ResultsDoc -> Bool
    $c/= :: ResultsDoc -> ResultsDoc -> Bool
    /= :: ResultsDoc -> ResultsDoc -> Bool
    Eq, Eq ResultsDoc
    Eq ResultsDoc =>
    (ResultsDoc -> ResultsDoc -> Ordering)
    -> (ResultsDoc -> ResultsDoc -> Bool)
    -> (ResultsDoc -> ResultsDoc -> Bool)
    -> (ResultsDoc -> ResultsDoc -> Bool)
    -> (ResultsDoc -> ResultsDoc -> Bool)
    -> (ResultsDoc -> ResultsDoc -> ResultsDoc)
    -> (ResultsDoc -> ResultsDoc -> ResultsDoc)
    -> Ord ResultsDoc
    ResultsDoc -> ResultsDoc -> Bool
    ResultsDoc -> ResultsDoc -> Ordering
    ResultsDoc -> ResultsDoc -> ResultsDoc
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ResultsDoc -> ResultsDoc -> Ordering
    compare :: ResultsDoc -> ResultsDoc -> Ordering
    $c< :: ResultsDoc -> ResultsDoc -> Bool
    < :: ResultsDoc -> ResultsDoc -> Bool
    $c<= :: ResultsDoc -> ResultsDoc -> Bool
    <= :: ResultsDoc -> ResultsDoc -> Bool
    $c> :: ResultsDoc -> ResultsDoc -> Bool
    > :: ResultsDoc -> ResultsDoc -> Bool
    $c>= :: ResultsDoc -> ResultsDoc -> Bool
    >= :: ResultsDoc -> ResultsDoc -> Bool
    $cmax :: ResultsDoc -> ResultsDoc -> ResultsDoc
    max :: ResultsDoc -> ResultsDoc -> ResultsDoc
    $cmin :: ResultsDoc -> ResultsDoc -> ResultsDoc
    min :: ResultsDoc -> ResultsDoc -> ResultsDoc
    Ord, Int -> ResultsDoc -> ShowS
    [ResultsDoc] -> ShowS
    ResultsDoc -> String
    (Int -> ResultsDoc -> ShowS)
    -> (ResultsDoc -> String)
    -> ([ResultsDoc] -> ShowS)
    -> Show ResultsDoc
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ResultsDoc -> ShowS
    showsPrec :: Int -> ResultsDoc -> ShowS
    $cshow :: ResultsDoc -> String
    show :: ResultsDoc -> String
    $cshowList :: [ResultsDoc] -> ShowS
    showList :: [ResultsDoc] -> ShowS
    Show)

    -- | Documentation for a single return value of a function.
    data ResultValueDoc = ResultValueDoc
      { ResultValueDoc -> TypeSpec
    resultValueType :: TypeSpec
      , ResultValueDoc -> Text
    resultValueDescription :: Text
      }
      deriving (ResultValueDoc -> ResultValueDoc -> Bool
    (ResultValueDoc -> ResultValueDoc -> Bool)
    -> (ResultValueDoc -> ResultValueDoc -> Bool) -> Eq ResultValueDoc
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ResultValueDoc -> ResultValueDoc -> Bool
    == :: ResultValueDoc -> ResultValueDoc -> Bool
    $c/= :: ResultValueDoc -> ResultValueDoc -> Bool
    /= :: ResultValueDoc -> ResultValueDoc -> Bool
    Eq, Eq ResultValueDoc
    Eq ResultValueDoc =>
    (ResultValueDoc -> ResultValueDoc -> Ordering)
    -> (ResultValueDoc -> ResultValueDoc -> Bool)
    -> (ResultValueDoc -> ResultValueDoc -> Bool)
    -> (ResultValueDoc -> ResultValueDoc -> Bool)
    -> (ResultValueDoc -> ResultValueDoc -> Bool)
    -> (ResultValueDoc -> ResultValueDoc -> ResultValueDoc)
    -> (ResultValueDoc -> ResultValueDoc -> ResultValueDoc)
    -> Ord ResultValueDoc
    ResultValueDoc -> ResultValueDoc -> Bool
    ResultValueDoc -> ResultValueDoc -> Ordering
    ResultValueDoc -> ResultValueDoc -> ResultValueDoc
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ResultValueDoc -> ResultValueDoc -> Ordering
    compare :: ResultValueDoc -> ResultValueDoc -> Ordering
    $c< :: ResultValueDoc -> ResultValueDoc -> Bool
    < :: ResultValueDoc -> ResultValueDoc -> Bool
    $c<= :: ResultValueDoc -> ResultValueDoc -> Bool
    <= :: ResultValueDoc -> ResultValueDoc -> Bool
    $c> :: ResultValueDoc -> ResultValueDoc -> Bool
    > :: ResultValueDoc -> ResultValueDoc -> Bool
    $c>= :: ResultValueDoc -> ResultValueDoc -> Bool
    >= :: ResultValueDoc -> ResultValueDoc -> Bool
    $cmax :: ResultValueDoc -> ResultValueDoc -> ResultValueDoc
    max :: ResultValueDoc -> ResultValueDoc -> ResultValueDoc
    $cmin :: ResultValueDoc -> ResultValueDoc -> ResultValueDoc
    min :: ResultValueDoc -> ResultValueDoc -> ResultValueDoc
    Ord, Int -> ResultValueDoc -> ShowS
    [ResultValueDoc] -> ShowS
    ResultValueDoc -> String
    (Int -> ResultValueDoc -> ShowS)
    -> (ResultValueDoc -> String)
    -> ([ResultValueDoc] -> ShowS)
    -> Show ResultValueDoc
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ResultValueDoc -> ShowS
    showsPrec :: Int -> ResultValueDoc -> ShowS
    $cshow :: ResultValueDoc -> String
    show :: ResultValueDoc -> String
    $cshowList :: [ResultValueDoc] -> ShowS
    showList :: [ResultValueDoc] -> ShowS
    Show)