Skip to main content

soma_provider_guest/
lib.rs

1//! Guest-side helpers for the `soma:provider@1.0.0` component world.
2//!
3//! Business logic should implement [`ProviderCore`], leaving the tiny
4//! `wit-bindgen` export adapter in the final component crate. The same core can
5//! then be reused by PyO3 and native-provider adapters.
6
7wit_bindgen::generate!({
8    path: "../../../wit/soma-provider",
9    world: "provider",
10});
11
12/// Reusable business-logic boundary shared by component, PyO3, and native
13/// provider adapters.
14pub trait ProviderCore {
15    fn invoke(input: serde_json::Value) -> Result<serde_json::Value, String>;
16}
17
18/// Decode the canonical JSON envelope, invoke a reusable core, and encode its
19/// output for the WIT adapter.
20pub fn invoke_json<P: ProviderCore>(input: String) -> Result<String, String> {
21    let input = serde_json::from_str(&input).map_err(|error| error.to_string())?;
22    let output = P::invoke(input)?;
23    serde_json::to_string(&output).map_err(|error| error.to_string())
24}
25
26/// Perform a capability-mediated HTTP request.
27pub fn http(request: &impl serde::Serialize) -> Result<serde_json::Value, String> {
28    let request = serde_json::to_string(request).map_err(|error| error.to_string())?;
29    let result = soma::provider::host::http(&request)?;
30    serde_json::from_str(&result).map_err(|error| error.to_string())
31}
32
33/// Resolve a named secret handle declared by the provider.
34pub fn secret(name: &str) -> Result<String, String> {
35    soma::provider::host::secret(name)
36}
37
38/// Read a JSON value from the provider's declared state namespace.
39pub fn state_get(key: &str) -> Result<serde_json::Value, String> {
40    let result = soma::provider::host::state_get(key)?;
41    serde_json::from_str(&result).map_err(|error| error.to_string())
42}
43
44/// Write a JSON value into the provider's declared state namespace.
45pub fn state_put(key: &str, value: &impl serde::Serialize) -> Result<(), String> {
46    let value = serde_json::to_string(value).map_err(|error| error.to_string())?;
47    soma::provider::host::state_put(key, &value)
48}
49
50/// Emit a bounded structured provider log.
51pub fn log(level: &str, message: &str, fields: &impl serde::Serialize) -> Result<(), String> {
52    let fields = serde_json::to_string(fields).map_err(|error| error.to_string())?;
53    soma::provider::host::log(level, message, &fields)
54}
55
56/// Emit a provider metric.
57pub fn metric(name: &str, value: f64, attributes: &impl serde::Serialize) -> Result<(), String> {
58    let attributes = serde_json::to_string(attributes).map_err(|error| error.to_string())?;
59    soma::provider::host::metric(name, value, &attributes)
60}
61
62/// Report invocation progress.
63pub fn progress(current: u64, total: Option<u64>, message: Option<&str>) -> Result<(), String> {
64    soma::provider::host::progress(current, total, message)
65}