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

    Marshaling and documenting Haskell functions.
    -}
    module HsLua.Packaging.Types
      ( -- * Documented Lua objects
        Module (..)
      , Field (..)
      , DocumentedFunction (..)
      , DocumentedType
        -- * Documentation types
      , DocumentationObject (..)
      , ModuleDoc (..)
      , FunctionDoc (..)
      , TypeDoc (..)
      , ParameterDoc (..)
      , ResultsDoc (..)
      , ResultValueDoc (..)
      , FieldDoc (..)
      -- * Type classes
      , HasName (..)
      , HasDescription (..)
      ) where

    import Data.Text (Text)
    import Data.Version (Version)
    import HsLua.Core (LuaE, Name (fromName), NumResults)
    import HsLua.ObjectOrientation (Operation, UDType)
    import HsLua.Typing (TypeSpec)
    import qualified HsLua.Core.Utf8 as Utf8

    -- | Type definitions containing documented functions.
    type DocumentedType e a = UDType e (DocumentedFunction e) a

    -- | 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]
        -- ^ Lua initializers for the types that come with this module.
        --   Useful to force full initialization of all metatables.
      , forall e. Module e -> [TypeDoc]
    moduleTypeDocs :: [TypeDoc]
        -- ^ Documentation for the types that are associated with this module.
      }

    -- | Self-documenting module field
    data Field e = Field
      { forall e. Field e -> Name
    fieldName :: Name
      , forall e. Field e -> FieldDoc
    fieldDoc :: FieldDoc
      , 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
    --

    -- | Module documentation
    data ModuleDoc = ModuleDoc
      { ModuleDoc -> Text
    moduleDocName        :: Text          -- ^ module name
      , ModuleDoc -> Text
    moduleDocDescription :: Text          -- ^ textual module description
      , ModuleDoc -> [FieldDoc]
    moduleDocFields      :: [FieldDoc]    -- ^ module fields
      , ModuleDoc -> [FunctionDoc]
    moduleDocFunctions   :: [FunctionDoc] -- ^ module functions
      , ModuleDoc -> [TypeDoc]
    moduleDocTypes       :: [TypeDoc]     -- ^ module-associated types
      }
      deriving (ModuleDoc -> ModuleDoc -> Bool
    (ModuleDoc -> ModuleDoc -> Bool)
    -> (ModuleDoc -> ModuleDoc -> Bool) -> Eq ModuleDoc
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ModuleDoc -> ModuleDoc -> Bool
    == :: ModuleDoc -> ModuleDoc -> Bool
    $c/= :: ModuleDoc -> ModuleDoc -> Bool
    /= :: ModuleDoc -> ModuleDoc -> Bool
    Eq, Eq ModuleDoc
    Eq ModuleDoc =>
    (ModuleDoc -> ModuleDoc -> Ordering)
    -> (ModuleDoc -> ModuleDoc -> Bool)
    -> (ModuleDoc -> ModuleDoc -> Bool)
    -> (ModuleDoc -> ModuleDoc -> Bool)
    -> (ModuleDoc -> ModuleDoc -> Bool)
    -> (ModuleDoc -> ModuleDoc -> ModuleDoc)
    -> (ModuleDoc -> ModuleDoc -> ModuleDoc)
    -> Ord ModuleDoc
    ModuleDoc -> ModuleDoc -> Bool
    ModuleDoc -> ModuleDoc -> Ordering
    ModuleDoc -> ModuleDoc -> ModuleDoc
    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 :: ModuleDoc -> ModuleDoc -> Ordering
    compare :: ModuleDoc -> ModuleDoc -> Ordering
    $c< :: ModuleDoc -> ModuleDoc -> Bool
    < :: ModuleDoc -> ModuleDoc -> Bool
    $c<= :: ModuleDoc -> ModuleDoc -> Bool
    <= :: ModuleDoc -> ModuleDoc -> Bool
    $c> :: ModuleDoc -> ModuleDoc -> Bool
    > :: ModuleDoc -> ModuleDoc -> Bool
    $c>= :: ModuleDoc -> ModuleDoc -> Bool
    >= :: ModuleDoc -> ModuleDoc -> Bool
    $cmax :: ModuleDoc -> ModuleDoc -> ModuleDoc
    max :: ModuleDoc -> ModuleDoc -> ModuleDoc
    $cmin :: ModuleDoc -> ModuleDoc -> ModuleDoc
    min :: ModuleDoc -> ModuleDoc -> ModuleDoc
    Ord, Int -> ModuleDoc -> ShowS
    [ModuleDoc] -> ShowS
    ModuleDoc -> String
    (Int -> ModuleDoc -> ShowS)
    -> (ModuleDoc -> String)
    -> ([ModuleDoc] -> ShowS)
    -> Show ModuleDoc
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ModuleDoc -> ShowS
    showsPrec :: Int -> ModuleDoc -> ShowS
    $cshow :: ModuleDoc -> String
    show :: ModuleDoc -> String
    $cshowList :: [ModuleDoc] -> ShowS
    showList :: [ModuleDoc] -> ShowS
    Show)

    -- | Documentation for a Haskell function
    data FunctionDoc = FunDoc
      { FunctionDoc -> Text
    funDocName          :: Text
      , FunctionDoc -> Text
    funDocDescription   :: Text
      , FunctionDoc -> [ParameterDoc]
    funDocParameters    :: [ParameterDoc]
      , FunctionDoc -> ResultsDoc
    funDocResults       :: ResultsDoc
      , FunctionDoc -> Maybe Version
    funDocSince         :: 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)

    -- | Documentation for a module field.
    data FieldDoc = FieldDoc
      { FieldDoc -> Text
    fieldDocName :: Text
      , FieldDoc -> TypeSpec
    fieldDocType :: TypeSpec
      , FieldDoc -> Text
    fieldDocDescription :: Text
      }
      deriving (FieldDoc -> FieldDoc -> Bool
    (FieldDoc -> FieldDoc -> Bool)
    -> (FieldDoc -> FieldDoc -> Bool) -> Eq FieldDoc
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: FieldDoc -> FieldDoc -> Bool
    == :: FieldDoc -> FieldDoc -> Bool
    $c/= :: FieldDoc -> FieldDoc -> Bool
    /= :: FieldDoc -> FieldDoc -> Bool
    Eq, Eq FieldDoc
    Eq FieldDoc =>
    (FieldDoc -> FieldDoc -> Ordering)
    -> (FieldDoc -> FieldDoc -> Bool)
    -> (FieldDoc -> FieldDoc -> Bool)
    -> (FieldDoc -> FieldDoc -> Bool)
    -> (FieldDoc -> FieldDoc -> Bool)
    -> (FieldDoc -> FieldDoc -> FieldDoc)
    -> (FieldDoc -> FieldDoc -> FieldDoc)
    -> Ord FieldDoc
    FieldDoc -> FieldDoc -> Bool
    FieldDoc -> FieldDoc -> Ordering
    FieldDoc -> FieldDoc -> FieldDoc
    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 :: FieldDoc -> FieldDoc -> Ordering
    compare :: FieldDoc -> FieldDoc -> Ordering
    $c< :: FieldDoc -> FieldDoc -> Bool
    < :: FieldDoc -> FieldDoc -> Bool
    $c<= :: FieldDoc -> FieldDoc -> Bool
    <= :: FieldDoc -> FieldDoc -> Bool
    $c> :: FieldDoc -> FieldDoc -> Bool
    > :: FieldDoc -> FieldDoc -> Bool
    $c>= :: FieldDoc -> FieldDoc -> Bool
    >= :: FieldDoc -> FieldDoc -> Bool
    $cmax :: FieldDoc -> FieldDoc -> FieldDoc
    max :: FieldDoc -> FieldDoc -> FieldDoc
    $cmin :: FieldDoc -> FieldDoc -> FieldDoc
    min :: FieldDoc -> FieldDoc -> FieldDoc
    Ord, Int -> FieldDoc -> ShowS
    [FieldDoc] -> ShowS
    FieldDoc -> String
    (Int -> FieldDoc -> ShowS)
    -> (FieldDoc -> String) -> ([FieldDoc] -> ShowS) -> Show FieldDoc
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> FieldDoc -> ShowS
    showsPrec :: Int -> FieldDoc -> ShowS
    $cshow :: FieldDoc -> String
    show :: FieldDoc -> String
    $cshowList :: [FieldDoc] -> ShowS
    showList :: [FieldDoc] -> ShowS
    Show)

    -- | Documentation of a data type.
    data TypeDoc = TypeDoc
      { TypeDoc -> Text
    typeDocName        :: Text
      , TypeDoc -> Text
    typeDocDescription :: Text
      , TypeDoc -> [(Operation, FunctionDoc)]
    typeDocOperations  :: [(Operation, FunctionDoc)]
      , TypeDoc -> [FunctionDoc]
    typeDocMethods     :: [FunctionDoc]
      }
      deriving (TypeDoc -> TypeDoc -> Bool
    (TypeDoc -> TypeDoc -> Bool)
    -> (TypeDoc -> TypeDoc -> Bool) -> Eq TypeDoc
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: TypeDoc -> TypeDoc -> Bool
    == :: TypeDoc -> TypeDoc -> Bool
    $c/= :: TypeDoc -> TypeDoc -> Bool
    /= :: TypeDoc -> TypeDoc -> Bool
    Eq, Eq TypeDoc
    Eq TypeDoc =>
    (TypeDoc -> TypeDoc -> Ordering)
    -> (TypeDoc -> TypeDoc -> Bool)
    -> (TypeDoc -> TypeDoc -> Bool)
    -> (TypeDoc -> TypeDoc -> Bool)
    -> (TypeDoc -> TypeDoc -> Bool)
    -> (TypeDoc -> TypeDoc -> TypeDoc)
    -> (TypeDoc -> TypeDoc -> TypeDoc)
    -> Ord TypeDoc
    TypeDoc -> TypeDoc -> Bool
    TypeDoc -> TypeDoc -> Ordering
    TypeDoc -> TypeDoc -> TypeDoc
    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 :: TypeDoc -> TypeDoc -> Ordering
    compare :: TypeDoc -> TypeDoc -> Ordering
    $c< :: TypeDoc -> TypeDoc -> Bool
    < :: TypeDoc -> TypeDoc -> Bool
    $c<= :: TypeDoc -> TypeDoc -> Bool
    <= :: TypeDoc -> TypeDoc -> Bool
    $c> :: TypeDoc -> TypeDoc -> Bool
    > :: TypeDoc -> TypeDoc -> Bool
    $c>= :: TypeDoc -> TypeDoc -> Bool
    >= :: TypeDoc -> TypeDoc -> Bool
    $cmax :: TypeDoc -> TypeDoc -> TypeDoc
    max :: TypeDoc -> TypeDoc -> TypeDoc
    $cmin :: TypeDoc -> TypeDoc -> TypeDoc
    min :: TypeDoc -> TypeDoc -> TypeDoc
    Ord, Int -> TypeDoc -> ShowS
    [TypeDoc] -> ShowS
    TypeDoc -> String
    (Int -> TypeDoc -> ShowS)
    -> (TypeDoc -> String) -> ([TypeDoc] -> ShowS) -> Show TypeDoc
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> TypeDoc -> ShowS
    showsPrec :: Int -> TypeDoc -> ShowS
    $cshow :: TypeDoc -> String
    show :: TypeDoc -> String
    $cshowList :: [TypeDoc] -> ShowS
    showList :: [TypeDoc] -> ShowS
    Show)

    -- | Documentation for any of the supported Lua objects.
    data DocumentationObject
      = DocObjectFunction FunctionDoc
      | DocObjectModule   ModuleDoc
      | DocObjectType     TypeDoc
      deriving (DocumentationObject -> DocumentationObject -> Bool
    (DocumentationObject -> DocumentationObject -> Bool)
    -> (DocumentationObject -> DocumentationObject -> Bool)
    -> Eq DocumentationObject
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DocumentationObject -> DocumentationObject -> Bool
    == :: DocumentationObject -> DocumentationObject -> Bool
    $c/= :: DocumentationObject -> DocumentationObject -> Bool
    /= :: DocumentationObject -> DocumentationObject -> Bool
    Eq, Eq DocumentationObject
    Eq DocumentationObject =>
    (DocumentationObject -> DocumentationObject -> Ordering)
    -> (DocumentationObject -> DocumentationObject -> Bool)
    -> (DocumentationObject -> DocumentationObject -> Bool)
    -> (DocumentationObject -> DocumentationObject -> Bool)
    -> (DocumentationObject -> DocumentationObject -> Bool)
    -> (DocumentationObject
        -> DocumentationObject -> DocumentationObject)
    -> (DocumentationObject
        -> DocumentationObject -> DocumentationObject)
    -> Ord DocumentationObject
    DocumentationObject -> DocumentationObject -> Bool
    DocumentationObject -> DocumentationObject -> Ordering
    DocumentationObject -> DocumentationObject -> DocumentationObject
    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 :: DocumentationObject -> DocumentationObject -> Ordering
    compare :: DocumentationObject -> DocumentationObject -> Ordering
    $c< :: DocumentationObject -> DocumentationObject -> Bool
    < :: DocumentationObject -> DocumentationObject -> Bool
    $c<= :: DocumentationObject -> DocumentationObject -> Bool
    <= :: DocumentationObject -> DocumentationObject -> Bool
    $c> :: DocumentationObject -> DocumentationObject -> Bool
    > :: DocumentationObject -> DocumentationObject -> Bool
    $c>= :: DocumentationObject -> DocumentationObject -> Bool
    >= :: DocumentationObject -> DocumentationObject -> Bool
    $cmax :: DocumentationObject -> DocumentationObject -> DocumentationObject
    max :: DocumentationObject -> DocumentationObject -> DocumentationObject
    $cmin :: DocumentationObject -> DocumentationObject -> DocumentationObject
    min :: DocumentationObject -> DocumentationObject -> DocumentationObject
    Ord, Int -> DocumentationObject -> ShowS
    [DocumentationObject] -> ShowS
    DocumentationObject -> String
    (Int -> DocumentationObject -> ShowS)
    -> (DocumentationObject -> String)
    -> ([DocumentationObject] -> ShowS)
    -> Show DocumentationObject
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> DocumentationObject -> ShowS
    showsPrec :: Int -> DocumentationObject -> ShowS
    $cshow :: DocumentationObject -> String
    show :: DocumentationObject -> String
    $cshowList :: [DocumentationObject] -> ShowS
    showList :: [DocumentationObject] -> ShowS
    Show)

    --
    -- Type Classes
    --

    -- | Objects that have descriptions.
    class HasDescription a where
      getDescription :: a -> Text
      setDescription :: a -> Text -> a

    instance HasDescription FieldDoc where
      getDescription :: FieldDoc -> Text
    getDescription = FieldDoc -> Text
    fieldDocDescription
      setDescription :: FieldDoc -> Text -> FieldDoc
    setDescription FieldDoc
    fd Text
    descr = FieldDoc
    fd { fieldDocDescription = descr }

    instance HasDescription (Module e) where
      getDescription :: Module e -> Text
    getDescription = Module e -> Text
    forall e. Module e -> Text
    moduleDescription
      setDescription :: Module e -> Text -> Module e
    setDescription Module e
    mdl Text
    descr = Module e
    mdl { moduleDescription = descr }

    instance HasDescription ModuleDoc where
      getDescription :: ModuleDoc -> Text
    getDescription = ModuleDoc -> Text
    moduleDocDescription
      setDescription :: ModuleDoc -> Text -> ModuleDoc
    setDescription ModuleDoc
    md Text
    descr = ModuleDoc
    md { moduleDocDescription = descr }

    instance HasDescription (Field e) where
      getDescription :: Field e -> Text
    getDescription = FieldDoc -> Text
    fieldDocDescription (FieldDoc -> Text) -> (Field e -> FieldDoc) -> Field e -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Field e -> FieldDoc
    forall e. Field e -> FieldDoc
    fieldDoc
      setDescription :: Field e -> Text -> Field e
    setDescription Field e
    fld Text
    descr =
        let doc :: FieldDoc
    doc = Field e -> FieldDoc
    forall e. Field e -> FieldDoc
    fieldDoc Field e
    fld
        in Field e
    fld { fieldDoc = setDescription doc descr }

    -- | Named objects
    class HasName a where
      getName :: a -> Name
      setName :: a -> Name -> a

    instance HasName (Field e) where
      getName :: Field e -> Name
    getName = Field e -> Name
    forall e. Field e -> Name
    fieldName
      setName :: Field e -> Name -> Field e
    setName Field e
    fd Name
    name =
        let doc :: FieldDoc
    doc = Field e -> FieldDoc
    forall e. Field e -> FieldDoc
    fieldDoc Field e
    fd
        in Field e
    fd
        { fieldName = name
        , fieldDoc = doc { fieldDocName = Utf8.toText $ fromName name }
        }

    instance HasName (Module e) where
      getName :: Module e -> Name
    getName = Module e -> Name
    forall e. Module e -> Name
    moduleName
      setName :: Module e -> Name -> Module e
    setName Module e
    mdl Name
    name = Module e
    mdl { moduleName = name }

    instance HasName (DocumentedFunction e) where
      getName :: DocumentedFunction e -> Name
    getName = DocumentedFunction e -> Name
    forall e. DocumentedFunction e -> Name
    functionName
      setName :: DocumentedFunction e -> Name -> DocumentedFunction e
    setName DocumentedFunction e
    fn Name
    name =
        let fnDoc :: FunctionDoc
    fnDoc = DocumentedFunction e -> FunctionDoc
    forall e. DocumentedFunction e -> FunctionDoc
    functionDoc DocumentedFunction e
    fn
        in DocumentedFunction e
    fn
           { functionName = name
           , functionDoc = fnDoc { funDocName = Utf8.toText $ fromName name }
           }