gaato/discord/app does not have a README file

    CommandCheck

    type CommandCheck = (CheckCtx) -> Bool raise HandlerError

    A command guard. Returning false produces HandlerError::CheckFailed; expected denials can instead raise a more specific HandlerError.

    ComponentWaiter

    type ComponentWaiter = async (String, Int?) ->
    ComponentCtx
    ?

    Executor-provided lookup behind wait_for_component: resolves the next component interaction matching a custom id, with an optional timeout in milliseconds.

    ErrorPolicy

    type ErrorPolicy = async (FailureCtx, Error) -> Unit

    Policy invoked for interaction, event, and service failures.

    InteractionMiddleware

    type InteractionMiddleware = async (InteractionCtx, async () -> Unit) -> Unit

    Middleware around interaction dispatch: receives the read-only context and a next continuation. Call next() to continue the chain; skip it (typically after InteractionCtx::respond) to short-circuit the handler.

    Spawner

    type Spawner = async (async () -> Unit) -> Unit

    Executor-provided function that runs a handler task concurrently on the surrounding async runtime.

    AppConfigError

    pub(all) suberror AppConfigError {
    EmptyToken
    DuplicateCommand(name~ : String)
    DuplicateCommandPath(command~ : String, path~ : String)
    NestedSubcommandGroup(command~ : String, path~ : String)
    ChoicesWithAutocomplete(command~ : String, path~ : String)
    RequiredOptionAfterOptional(command~ : String, path~ : String)
    InvalidModalFieldCount(custom_id~ : String, count~ : Int)
    DuplicateModalTextInput(custom_id~ : String, field~ : String)
    InvalidCooldown(command~ : String, seconds~ : Int)
    InvalidMaxInFlight(value~ : Int)
    } derive(
    Debug
    )

    Configuration errors detected before starting an application executor.

    AppDispatchError

    pub(all) suberror AppDispatchError {
    Failure(command~ : String, phase~ : ResponsePhase, source~ : Error)
    } derive(
    Debug
    )

    A command dispatch failure with its response phase and original cause.

    HandlerError

    pub(all) suberror HandlerError {
    UserMessage(message~ : String, ephemeral~ : Bool)
    GuildOnly
    DmOnly
    CheckFailed
    MissingPermission(
    Permissions
    )
    OnCooldown(retry_after_ms~ : Int64)
    InvalidArgument(String)
    } derive(
    Debug
    )

    Expected command failures that an error policy can present to the user.

    Raise these from handlers, checks, or app middleware; the application's ErrorPolicy turns them into user-facing responses. A permission guard computed with @util.channel_permissions typically raises MissingPermission:

    test "guard a handler with a permission requirement" {
    fn require_send_messages(permissions : @model.Permissions) -> Unit raise {
    let required = @model.Permissions::send_messages()
    if !permissions.contains(required) {
    raise @app.HandlerError::MissingPermission(required)
    }
    }

    try require_send_messages(@model.Permissions::none()) catch {
    @app.HandlerError::MissingPermission(_) => ()
    other => raise other
    } noraise {
    _ => fail("expected MissingPermission")
    }
    }

    ModalPrefillError

    pub(all) suberror ModalPrefillError {
    UnknownCustomId(custom_id~ : String)
    NonTextInput(custom_id~ : String)
    } derive(
    Debug
    )

    Invalid per-show text-input prefill configuration.

    App

    pub struct App {
    // private fields
    }

    Gateway-free application declarations shared by gateway and HTTP executors.

    App::App

    fn App::App(sync? : CommandSync, max_in_flight? : Int) -> App

    Create an application core. sync picks the command-sync strategy applied by sync_commands (default: overwrite global commands); max_in_flight caps concurrently running interaction handlers.

    App::attach

    Wire every registered command, component, modal, and autocomplete route into framework and return the AppCtx shared by handlers. Called by the built-in executors (Bot, the HTTP endpoint); only custom executors need it directly.

    App::autocomplete

    fn App::autocomplete(self : App, name : String, handler : async (
    AutocompleteCtx
    ) -> Unit) -> Unit

    Register a raw autocomplete handler. A raw handler takes precedence over Arg-level suggest handlers registered for the same command name.

    App::command

    fn[A] App::command(self : App, command : Command[A]) -> Unit

    Register a typed slash or context-menu command built with the command / user_command / message_command builders.

    App::error_policy

    fn App::error_policy(self : App, policy : async (FailureCtx, Error) -> Unit) -> Unit

    Replace the error policy invoked when a handler raises. The default policy maps HandlerError variants to ephemeral user-facing messages and warns about everything else.

    App::middleware

    fn App::middleware(self : App, middleware : async (InteractionCtx, async () -> Unit) -> Unit) -> Unit

    Install middleware around every command, component, and modal handler (not autocomplete). First installed is outermost. Runs inside the error policy: raising HandlerError behaves exactly like a failing check.

    App::on_component

    fn App::on_component(self : App, prefix~ : String, handler : ComponentHandler) -> Unit

    Route component interactions whose custom id starts with prefix to handler. Longer prefixes win when several match.

    App::on_modal

    fn[A] App::on_modal(self : App, modal : Modal[A], handler : ModalSubmitHandler[A]) -> Unit

    Route submissions of the typed modal to handler; field values are decoded through the modal's ModalFields before the handler runs.

    App::on_modal_raw

    fn App::on_modal_raw(self : App, prefix~ : String, handler : async (
    ModalCtx
    ) -> Unit) -> Unit

    Register a fully raw modal route without a typed modal definition.

    App::on_warn

    fn App::on_warn(self : App, hook : (String) -> Unit) -> Unit

    Replace the warning hook used for non-fatal diagnostics (default: println).

    App::register

    fn App::register(self : App, command : RegisteredCommand) -> Unit

    Register a type-erased command. App::command is the typed entry point; use this when composing pre-erased commands, e.g. from a plugin.

    App::report_failure

    async fn App::report_failure(self : App, origin : FailureOrigin, error : Error) -> Unit

    Run the error policy for a failure raised outside interaction dispatch. Executors use this for event and service handlers; the policy context has no response target in that case.

    App::serve

    Build a gateway-free dispatcher.

    When client is omitted, the endpoint owns a client created from token and closes it when group finishes. When application_id is omitted, this method always resolves it through GET /applications/@me, including when sync is false. Supplying both values avoids startup HTTP requests when synchronization is disabled.

    If sync is true, command synchronization follows the app's CommandSync setting; CommandSync::Disabled still performs no synchronization.

    App::spawner

    fn App::spawner(self : App, group :
    TaskGroup
    [Unit]) -> (async (async () -> Unit) -> Unit)

    Create a bounded task spawner for an executor-owned task group.

    App::sync_commands

    Push the declared command set to Discord following the CommandSync strategy chosen at construction: global, one or more guilds, or disabled.

    App::validate

    fn App::validate(self : App) -> Unit raise AppConfigError

    Check declarations for configuration errors: invalid command trees and cooldowns, invalid modal field counts, and duplicate modal text-input ids. Executors call this at startup; call it directly in a test to fail fast.

    App::warn

    fn App::warn(self : App, message : String) -> Unit

    Emit a message through the app's warning hook.

    AppCtx

    pub struct AppCtx {
    // private fields
    }

    Transport-neutral services available to interaction handlers.

    Executors construct these values; the public API exposes read-only accessors.

    AppCtx::application_id

    The application id learned during startup.

    AppCtx::application_ref

    The current application bound to its Discord REST client.

    AppCtx::http

    The Discord REST client used by this application.

    AppCtx::latency_ms

    fn AppCtx::latency_ms(self : AppCtx) -> Int64?

    The latest gateway heartbeat round-trip time in milliseconds. For a multi-shard bot, this is the arithmetic mean of shards that have measured latency. HTTP interaction executors and gateway connections awaiting their first heartbeat acknowledgement return None; use GatewayCtx::latency_ms() when the exact value for one shard is required.

    CheckCtx

    pub struct CheckCtx {
    // private fields
    }

    Read-only context passed to command checks before argument decoding and handler execution.

    CheckCtx::guild_id

    The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

    CheckCtx::guild_scope

    The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

    CheckCtx::interaction

    The full interaction payload.

    CheckCtx::scope

    Guild or DM invocation scope, carrying the invoking member or user.

    CheckCtx::user

    The invoking user.

    Command

    pub struct Command[A] {
    // private fields
    }

    An application-command definition with a context-aware decoder.

    Command::check

    fn[A] Command::check(self : Command[A], check : (CheckCtx) -> Bool raise HandlerError) -> Command[A]

    Add a pre-execution check. Checks run in registration order before argument decoding. Returning false is equivalent to HandlerError::CheckFailed.

    Command::cooldown

    fn[A] Command::cooldown(self : Command[A], seconds~ : Int, bucket? : CooldownBucket) -> Command[A]

    Apply a fixed-window cooldown to this command. The window starts when all checks pass, before argument decoding and handler execution.

    Command::erase

    fn[A] Command::erase(self : Command[A]) -> RegisteredCommand

    Erase the decoded argument type while retaining registration and dispatch.

    Command::spec

    The command registration specification.

    CommandReply

    pub(all) enum CommandReply {
    Message(InitialResponse)
    ShowModal(ModalHandle)
    }

    An initial response returned by an immediate command handler.

    CommandReply::message

    Construct an immediate message reply.

    CommandSync

    Where application commands are synchronized after the first READY.

    ComponentDeferredCtx

    pub struct ComponentDeferredCtx {
    // private fields
    }

    Component context available after a deferred callback.

    ComponentDeferredCtx::app

    The app-level services: the REST client and application id.

    ComponentDeferredCtx::custom_id

    fn ComponentDeferredCtx::custom_id(self : ComponentDeferredCtx) -> String

    The full custom id of the component that fired.

    ComponentDeferredCtx::edit_original

    Edit the original response after deferring. For DeferredUpdate handlers this edits the component's host message.

    ComponentDeferredCtx::followup

    Send a followup message after the initial deferred response.

    ComponentDeferredCtx::guild_id

    The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

    ComponentDeferredCtx::guild_scope

    The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

    ComponentDeferredCtx::interaction

    The full interaction payload.

    ComponentDeferredCtx::message

    The message hosting the component.

    ComponentDeferredCtx::raw

    Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

    ComponentDeferredCtx::scope

    Guild or DM invocation scope, carrying the invoking member or user.

    ComponentDeferredCtx::selected_channels

    Resolved partial channel objects for a channel select.

    ComponentDeferredCtx::selected_roles

    Resolved role objects for a role or mentionable select.

    ComponentDeferredCtx::selected_users

    Resolved user objects for a user or mentionable select.

    ComponentDeferredCtx::suffix

    fn ComponentDeferredCtx::suffix(self : ComponentDeferredCtx) -> String

    The custom id with this route's registered prefix stripped (the full id when it does not start with the prefix).

    ComponentDeferredCtx::user

    The invoking user.

    ComponentDeferredCtx::values

    fn ComponentDeferredCtx::values(self : ComponentDeferredCtx) -> Array[String]

    The raw string values selected in a select menu (empty for buttons).

    ComponentDeferredCtx::wait_for_component

    async fn ComponentDeferredCtx::wait_for_component(self : ComponentDeferredCtx, custom_id~ : String, timeout_ms? : Int) ->
    ComponentCtx
    ?

    Wait for the next component interaction with an exact custom id. Returns None on timeout, or immediately when running without a gateway connection.

    ComponentHandler

    pub(all) enum ComponentHandler {
    Immediate(async (ComponentImmediateCtx) -> ComponentReply)
    DeferredUpdate(async (ComponentDeferredCtx) -> Unit)
    DeferredMessage(ephemeral~ : Bool, async (ComponentDeferredCtx) -> Unit)
    Raw(async (
    ComponentCtx
    ) -> Unit)
    }

    Execution strategy for a component route.

    ComponentImmediateCtx

    pub struct ComponentImmediateCtx {
    // private fields
    }

    Read-only component context for handlers returning their initial callback.

    ComponentImmediateCtx::app

    The app-level services: the REST client and application id.

    ComponentImmediateCtx::custom_id

    fn ComponentImmediateCtx::custom_id(self : ComponentImmediateCtx) -> String

    The full custom id of the component that fired.

    ComponentImmediateCtx::guild_id

    The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

    ComponentImmediateCtx::guild_scope

    The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

    ComponentImmediateCtx::interaction

    The full interaction payload.

    ComponentImmediateCtx::message

    The message hosting the component.

    ComponentImmediateCtx::raw

    Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

    ComponentImmediateCtx::scope

    Guild or DM invocation scope, carrying the invoking member or user.

    ComponentImmediateCtx::selected_channels

    Resolved partial channel objects for a channel select.

    ComponentImmediateCtx::selected_roles

    Resolved role objects for a role or mentionable select.

    ComponentImmediateCtx::selected_users

    Resolved user objects for a user or mentionable select.

    ComponentImmediateCtx::suffix

    fn ComponentImmediateCtx::suffix(self : ComponentImmediateCtx) -> String

    The custom id with this route's registered prefix stripped (the full id when it does not start with the prefix).

    ComponentImmediateCtx::user

    The invoking user.

    ComponentImmediateCtx::values

    fn ComponentImmediateCtx::values(self : ComponentImmediateCtx) -> Array[String]

    The raw string values selected in a select menu (empty for buttons).

    ComponentReply

    pub(all) enum ComponentReply {
    UpdateMessage(content~ : String?, embeds~ : Array[
    Embed
    ]?, components~ : Array[
    Component
    ]?, allowed_mentions~ :
    AllowedMentions
    ?)
    Message(InitialResponse)
    ShowModal(ModalHandle)
    }

    Initial response returned by an immediate component handler.

    ComponentReply::message

    Reply with a new message; set ephemeral=true to show it only to the invoking user.

    ComponentReply::update_message

    Reply by editing the message that hosts the component.

    CooldownBucket

    pub(all) enum CooldownBucket {
    User
    Guild
    Global
    } derive(Eq,
    Debug
    )

    Identity used to share a fixed-window command cooldown.

    DeferredCtx

    pub struct DeferredCtx {
    // private fields
    }

    Command context made available after the initial deferred response.

    DeferredCtx::app

    fn DeferredCtx::app(self : DeferredCtx) -> AppCtx

    The app-level services: the REST client and application id.

    DeferredCtx::edit_original

    Edit the original response after deferring.

    DeferredCtx::followup

    Send a followup message after the initial deferred response.

    DeferredCtx::guild_id

    The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

    DeferredCtx::guild_scope

    The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

    DeferredCtx::interaction

    The full interaction payload.

    DeferredCtx::raw

    Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

    DeferredCtx::scope

    Guild or DM invocation scope, carrying the invoking member or user.

    DeferredCtx::user

    The invoking user.

    DeferredCtx::wait_for_component

    async fn DeferredCtx::wait_for_component(self : DeferredCtx, custom_id~ : String, timeout_ms? : Int) ->
    ComponentCtx
    ?

    Wait for the next component interaction with an exact custom id.

    FailureCtx

    pub struct FailureCtx {
    // private fields
    }

    Context handed to the error policy when a handler fails.

    FailureCtx::interaction

    The interaction payload associated with this failure. Event and service failures return None.

    FailureCtx::origin

    fn FailureCtx::origin(self : FailureCtx) -> FailureOrigin

    What opened the modal: a component (with its host message) or a command.

    FailureCtx::phase

    fn FailureCtx::phase(self : FailureCtx) -> ResponsePhase?

    How far the response lifecycle progressed before the failure, when an interaction was involved.

    FailureCtx::raw

    fn FailureCtx::raw(self : FailureCtx) -> FailureRaw?

    Access the underlying interaction context. Event and service failures return None. Direct responses through this escape hatch may fail unless the response phase is checked first; normally use respond_error().

    FailureCtx::respond_error

    async fn FailureCtx::respond_error(self : FailureCtx, content? : String, embeds? : Array[
    Embed
    ], components? : Array[
    Component
    ], files? : Array[
    FileUpload
    ], allowed_mentions? :
    AllowedMentions
    , ephemeral? : Bool) -> Unit

    Send an error without violating Discord's one-initial-response rule. Event and service failures have no response target; those calls are sent to the warning hook instead of guessing a channel.

    FailureCtx::user

    The user who invoked the failed interaction. Event and service failures return None.

    FailureOrigin

    pub(all) enum FailureOrigin {
    Command(name~ : String)
    Autocomplete(name~ : String)
    Component(custom_id~ : String)
    Modal(custom_id~ : String)
    Event(kind~ :
    EventKind
    )
    Service(name~ : String)
    } derive(
    Debug
    )

    The operation whose handler failed.

    FailureRaw

    The underlying interaction context for a failure.

    Event and service failures have no raw context. Responding through one of these contexts without first checking the response phase may fail; prefer FailureCtx::respond_error() for ordinary error responses.

    ImmediateCtx

    pub struct ImmediateCtx {
    // private fields
    }

    Read-only command context for handlers that return their initial response.

    ImmediateCtx::app

    fn ImmediateCtx::app(self : ImmediateCtx) -> AppCtx

    The app-level services: the REST client and application id.

    ImmediateCtx::guild_id

    The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

    ImmediateCtx::guild_scope

    The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

    ImmediateCtx::interaction

    The full interaction payload.

    ImmediateCtx::raw

    Escape hatch for advanced read-only inspection. Calling response methods on this raw value opts out of the immediate-handler response discipline.

    ImmediateCtx::scope

    Guild or DM invocation scope, carrying the invoking member or user.

    ImmediateCtx::user

    The invoking user.

    InitialResponse

    pub struct InitialResponse {
    // private fields
    }

    A declarative initial message response returned by an immediate handler.

    InitialResponse::message

    Construct an initial channel-message response.

    InteractionCtx

    pub struct InteractionCtx {
    // private fields
    }

    Read-only context handed to interaction middleware, before any initial response has been sent.

    InteractionCtx::guild_id

    The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

    InteractionCtx::guild_scope

    The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

    InteractionCtx::interaction

    The full interaction payload.

    InteractionCtx::respond

    async fn InteractionCtx::respond(self : InteractionCtx, message : String, ephemeral? : Bool) -> Unit

    Send the initial response from middleware, short-circuiting the handler.

    InteractionCtx::scope

    Guild or DM invocation scope, carrying the invoking member or user.

    InteractionCtx::target

    The routed command, component, or modal being invoked.

    InteractionCtx::user

    The invoking user.

    InteractionEndpoint

    pub struct InteractionEndpoint {
    // private fields
    }

    A gateway-free interaction dispatcher backed by a caller-owned task group.

    InteractionEndpoint::handle

    async fn InteractionEndpoint::handle(self : InteractionEndpoint, body : Json, deadline_ms? : Int) -> Json?

    Decode and dispatch an interaction JSON body.

    Returns callback JSON only for Reply. Multipart files cannot be expressed by this thin JSON API; callers that accept uploads should use handle_interaction and inspect InteractionOutcome::Reply.files.

    InteractionEndpoint::handle_interaction

    async fn InteractionEndpoint::handle_interaction(self : InteractionEndpoint, interaction :
    Interaction
    , deadline_ms? : Int) -> InteractionOutcome

    Dispatch one interaction and wait only for its initial response deadline. A timed-out handler remains attached to the app's task group and continues in the background.

    InteractionHandler

    pub(all) enum InteractionHandler[A] {
    Immediate(async (ImmediateCtx, A) -> CommandReply)
    Deferred(ephemeral~ : Bool, async (DeferredCtx, A) -> Unit)
    Raw(async (
    CommandCtx
    ) -> Unit)
    }

    Execution strategy for a typed application command.

    InteractionOutcome

    pub(all) enum InteractionOutcome {
    Reply(response~ :
    InteractionResponse
    , files~ : Array[
    FileUpload
    ]?)
    NoRoute
    NoResponse
    TimedOut
    } derive(
    Debug
    )

    The result of dispatching one HTTP-delivered interaction.

    InteractionTarget

    pub(all) enum InteractionTarget {
    Command(name~ : String)
    Component(custom_id~ : String)
    Modal(custom_id~ : String)
    } derive(
    Debug
    )

    The routed target of an interaction entering the middleware chain. Autocomplete, gateway events, and services never pass through it.
    pub struct Modal[A] {
    // private fields
    }

    A typed modal definition. The field decoder is retained for the matching on_modal registration while show erases it into a ModalHandle.

    Modal::show

    fn[A] Modal::show(self : Modal[A], state? : String, values? : Map[String, String]) -> ModalHandle raise ModalPrefillError

    Prepare a modal response, optionally appending opaque state after : and overriding text-input defaults by custom_id for this response only. Raises ModalPrefillError when an override key is unknown or does not name a text input.

    ModalDeferredCtx

    pub struct ModalDeferredCtx {
    // private fields
    }

    Modal-submit context available after a deferred response.

    ModalDeferredCtx::app

    The app-level services: the REST client and application id.

    ModalDeferredCtx::edit_original

    Edit the original response after deferring.

    ModalDeferredCtx::followup

    Send a followup message after the initial deferred response.

    ModalDeferredCtx::guild_id

    The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

    ModalDeferredCtx::guild_scope

    The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

    ModalDeferredCtx::interaction

    The full interaction payload.

    ModalDeferredCtx::origin

    What opened the modal: a component (with its host message) or a command.

    ModalDeferredCtx::raw

    Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

    ModalDeferredCtx::scope

    Guild or DM invocation scope, carrying the invoking member or user.

    ModalDeferredCtx::state

    fn ModalDeferredCtx::state(self : ModalDeferredCtx) -> String?

    The opaque state string passed to Modal::show, if any.

    ModalDeferredCtx::user

    The invoking user.

    ModalField

    pub struct ModalField[A] {
    // private fields
    }

    One typed input in a modal form.

    ModalField::map

    fn[A, B] ModalField::map(self : ModalField[A], f : (A) -> B) -> ModalField[B]

    Transform a decoded modal field without changing its emitted component.

    ModalField::optional

    fn[A] ModalField::optional(self : ModalField[A]) -> ModalField[A?]

    Make a modal field optional. Missing and empty submissions decode to None.

    ModalField::validate

    fn[A] ModalField::validate(self : ModalField[A], check : (A) -> String?) -> ModalField[A]

    Validate a decoded field. Returning a message rejects the submission.

    ModalField::with_default

    fn[A] ModalField::with_default(self : ModalField[A], value : A) -> ModalField[A]

    Use a default when a modal field is missing or empty.

    ModalFields

    pub struct ModalFields[A] {
    // private fields
    }

    A composable collection of typed modal inputs.

    ModalFields::map

    fn[A, B] ModalFields::map(self : ModalFields[A], f : (A) -> B) -> ModalFields[B]

    Transform the decoded value without changing the emitted components.

    ModalFields::map1

    fn[A, Z] ModalFields::map1(a : ModalField[A], f : (A) -> Z) -> ModalFields[Z]

    Build a modal's field set from one field, mapping its decoded value into the handler's argument type.

    ModalFields::map2

    fn[A, B, Z] ModalFields::map2(a : ModalField[A], b : ModalField[B], f : (A, B) -> Z) -> ModalFields[Z]

    Build a modal's field set from two fields, combining their decoded values with the final function argument.

    ModalFields::map3

    fn[A, B, C, Z] ModalFields::map3(a : ModalField[A], b : ModalField[B], c : ModalField[C], f : (A, B, C) -> Z) -> ModalFields[Z]

    Build a modal's field set from three fields, combining their decoded values with the final function argument.

    ModalFields::map4

    fn[A, B, C, D, Z] ModalFields::map4(a : ModalField[A], b : ModalField[B], c : ModalField[C], d : ModalField[D], f : (A, B, C, D) -> Z) -> ModalFields[Z]

    Build a modal's field set from four fields, combining their decoded values with the final function argument.

    ModalFields::map5

    fn[A, B, C, D, E, Z] ModalFields::map5(a : ModalField[A], b : ModalField[B], c : ModalField[C], d : ModalField[D], e : ModalField[E], f : (A, B, C, D, E) -> Z) -> ModalFields[Z]

    Build a modal's field set from five fields, combining their decoded values with the final function argument.

    ModalFields::of

    fn[A] ModalFields::of(field : ModalField[A]) -> ModalFields[A]

    Lift a single field into a ModalFields; combine further with zip and map, or use the mapN helpers directly.

    ModalFields::zip

    fn[A, B] ModalFields::zip(self : ModalFields[A], other : ModalFields[B]) -> ModalFields[(A, B)]

    Concatenate two field sets and pair their decoded values.

    ModalHandle

    pub struct ModalHandle {
    // private fields
    }

    A type-erased modal response ready to be returned by a command or component handler.

    ModalImmediateCtx

    pub struct ModalImmediateCtx {
    // private fields
    }

    Read-only modal-submit context for handlers returning an initial message.

    ModalImmediateCtx::app

    The app-level services: the REST client and application id.

    ModalImmediateCtx::guild_id

    The guild the interaction was invoked in, or None outside guilds. Use guild_scope() for flows that require a guild; this accessor is for maybe-guild flows where DMs are valid.

    ModalImmediateCtx::guild_scope

    The validated guild invocation. In a DM this raises HandlerError::GuildOnly, which the error policy renders normally.

    ModalImmediateCtx::interaction

    The full interaction payload.

    ModalImmediateCtx::origin

    What opened the modal: a component (with its host message) or a command.

    ModalImmediateCtx::raw

    Escape hatch for advanced inspection. Calling response methods on the raw value opts out of this wrapper's response discipline.

    ModalImmediateCtx::scope

    Guild or DM invocation scope, carrying the invoking member or user.

    ModalImmediateCtx::state

    fn ModalImmediateCtx::state(self : ModalImmediateCtx) -> String?

    The opaque state string passed to Modal::show, if any.

    ModalImmediateCtx::user

    The invoking user.

    ModalSubmitHandler

    pub(all) enum ModalSubmitHandler[A] {
    Immediate(async (ModalImmediateCtx, A) -> InitialResponse)
    Deferred(ephemeral~ : Bool, async (ModalDeferredCtx, A) -> Unit)
    Raw(async (
    ModalCtx
    ) -> Unit)
    }

    Execution strategy for a typed modal submission.

    RegisteredCommand

    pub struct RegisteredCommand {
    // private fields
    }

    A type-erased command consumed by an App executor.

    RegisteredCommand::name

    fn RegisteredCommand::name(self : RegisteredCommand) -> String

    The top-level command name used for routing.

    ResponsePhase

    pub(all) enum ResponsePhase {
    BeforeInitial
    AfterDeferred
    AfterInitial
    } derive(Eq,
    Debug
    )

    The response state when an interaction handler failed.

    SlashChild

    pub struct SlashChild {
    // private fields
    }

    A type-erased slash subcommand or subcommand group.

    commands_in_sync

    Whether Discord's registered commands already match the declarations.

    Command (type, name) pairs must form the same set. For each command, comparison follows the declaration shape recursively, ignoring server-owned fields such as ids and versions while preserving option and choice order.

    dm_only

    fn dm_only() -> ((CheckCtx) -> Bool raise HandlerError)

    Require a direct-message invocation.

    guild_only

    fn guild_only() -> ((CheckCtx) -> Bool raise HandlerError)

    Require a guild invocation.

    message_command

    Define a MESSAGE context-menu command.
    fn[A] modal(custom_id~ : String, title~ : String, fields~ : ModalFields[A]) -> Modal[A]

    Define a typed modal.

    test "construct and validate a typed modal" {
    let feedback = @app.modal(
    custom_id="feedback",
    title="Feedback",
    fields=@app.ModalFields::of(
    @app.text_field(custom_id="details", label="Details").optional(),
    ),
    )
    let app = @app.App(sync=Disabled)
    app.on_modal(feedback, Raw(_ => ()))
    app.validate()
    let _ : @app.ModalHandle = feedback.show(state="draft")
    }

    required_permissions

    fn required_permissions(required :
    Permissions
    ) -> ((CheckCtx) -> Bool raise HandlerError)

    Require effective guild permissions supplied on the interaction member. Discord does not provide member permissions for DM invocations.

    select_field

    fn select_field(custom_id~ : String, label~ : String, options~ : Array[
    SelectOption
    ], description? : String, placeholder? : String, min_values? : Int, max_values? : Int) -> ModalField[Array[String]]

    Define a modern label-wrapped string select.

    slash

    fn[A] slash(name~ : String, description~ : String, args~ :
    Args
    [A], handler~ : InteractionHandler[A], default_member_permissions? :
    Permissions
    , nsfw? : Bool, integration_types? : Array[
    ApplicationIntegrationType
    ], contexts? : Array[
    InteractionContextType
    ], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> Command[A]

    Define a typed slash command.

    test "inspect a slash-command registration spec" {
    let command = @app.slash(
    name="echo",
    description="Echo text",
    args=@interaction.Args::of(
    @interaction.arg_string(name="text", description="Text to echo"),
    ),
    handler=Raw(_ => ()),
    )
    json_inspect(command.spec().to_json(), content={
    "name": "echo",
    "description": "Echo text",
    "options": [
    {
    "type": 3,
    "name": "text",
    "description": "Text to echo",
    "required": true,
    },
    ],
    })
    }

    slash_group

    fn slash_group(name~ : String, description~ : String, children~ : Array[SlashChild], default_member_permissions? :
    Permissions
    , nsfw? : Bool, integration_types? : Array[
    ApplicationIntegrationType
    ], contexts? : Array[
    InteractionContextType
    ], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> Command[Unit]

    Define a slash command whose children dispatch by submitted option path.

    subcommand

    fn[A] subcommand(name~ : String, description~ : String, args~ :
    Args
    [A], handler~ : InteractionHandler[A], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> SlashChild

    Define a typed slash subcommand.

    subcommand_group

    fn subcommand_group(name~ : String, description~ : String, children~ : Array[SlashChild], name_localizations? : Map[String, String], description_localizations? : Map[String, String]) -> SlashChild

    Define a slash subcommand group. Nested groups are retained for validation and rejected by App::validate, never by panic or abort here.

    text_field

    fn text_field(custom_id~ : String, label~ : String, style? :
    TextInputStyle
    , description? : String, placeholder? : String, min_length? : Int, max_length? : Int, value? : String) -> ModalField[String]

    Define a modern label-wrapped text input. value is its static prefill; Modal::show(values=...) can override it for one response.

    user_command

    Define a USER context-menu command.

    test "inspect context-menu command kinds" {
    let user = @app.user_command(name="Inspect user", handler=Raw(_ => ()))
    let message = @app.message_command(
    name="Inspect message",
    handler=Raw(_ => ()),
    )
    json_inspect(user.spec().to_json(), content={
    "name": "Inspect user",
    "description": "",
    "type": 2,
    })
    json_inspect(message.spec().to_json(), content={
    "name": "Inspect message",
    "description": "",
    "type": 3,
    })
    }