Skip to main content

act_runtime/
sessions.rs

1//! Host-side typed handles for the generated `act:sessions/session-provider`
2//! bindings.
3//!
4//! `act-world` declares `session-provider` as an export, but it is opt-in:
5//! stateless components do not export it. The host therefore binds it through
6//! a per-interface `GuestIndices::new` lookup that is allowed to fail —
7//! `instantiate_component` turns that failure into `None`, so components
8//! without session-provider instantiate fine.
9//!
10//! `Session`, `Error` and `Metadata` come straight from the generated
11//! bindings (the same `act:core/types` records the tool-provider uses, shared
12//! via the single `act-world` bindgen invocation).
13
14use wasmtime::component::TypedFunc;
15
16use super::exports::act::sessions::session_provider::Guest;
17// `act:sessions@0.2.0` moved the `session` record into `act:sessions/types`;
18// `error` / `metadata` resolve through `act:core/types`. Only the `Guest`
19// (and its typed-func accessors) still live in `session_provider`.
20use super::act::core::types::{Error, Metadata};
21
22/// `act:sessions/types.session` — re-exported from the generated bindings so
23/// callers keep referring to `sessions::Session`.
24pub use super::act::sessions::types::Session;
25
26// ── Typed function aliases (matching the WIT signatures) ───────────────────
27
28/// `get-open-session-args-schema(metadata) -> result<string, error>`
29type GetOpenSessionArgsSchemaFn = TypedFunc<(Metadata,), (Result<String, Error>,)>;
30
31/// `open-session(args: metadata, metadata: metadata) -> result<session, error>`
32type OpenSessionFn = TypedFunc<(Metadata, Metadata), (Result<Session, Error>,)>;
33
34/// `close-session(session-id: string)`
35type CloseSessionFn = TypedFunc<(String,), ()>;
36
37/// Typed handles to the three session-provider functions of one component
38/// instance, derived from the generated session `Guest`.
39#[derive(Clone)]
40pub struct SessionProvider {
41    pub get_open_session_args_schema: GetOpenSessionArgsSchemaFn,
42    pub open_session: OpenSessionFn,
43    pub close_session: CloseSessionFn,
44}
45
46impl SessionProvider {
47    /// Build typed handles from the generated session-provider `Guest`.
48    pub fn from_guest(guest: &Guest) -> Self {
49        Self {
50            get_open_session_args_schema: guest.func_get_open_session_args_schema(),
51            open_session: guest.func_open_session(),
52            // `close-session` is a sync WIT func, so bindgen types its accessor
53            // `TypedFunc<(&str,), ()>`. `call_concurrent` (used to drive it
54            // through the async store, like the other two) rejects that because
55            // its params must be `'static`. Re-type the same underlying `Func`
56            // to owned `(String,)`; the lowering is identical (both lower a
57            // `string`), which is what makes the `new_unchecked` sound.
58            close_session: unsafe { TypedFunc::new_unchecked(*guest.func_close_session().func()) },
59        }
60    }
61}