//! Use typed calls from discovered provider documents in `imports/`. //! Generated modules own the wire types, so calls need no manual JSON. //! The detached HTTP service survives this consumer. Its endpoint refers to that service's process-local state. //! Copy fresh documents from `/proc/core/plugins//discover.json` after an interface changes. use sausage_plugin::{Result, rpc, schema}; sausage_plugin::import!("notes"); sausage_plugin::import!("www"); sausage_plugin::import!("secrets"); /// Demonstrate typed imports without manual JSON messages. struct Consumer; /// A note for the imported notes plugin. #[schema] struct NoteParams { /// The text to append. text: String, } /// The text and HTTP port for this demonstration. #[schema] struct DemoParams { /// The note text to append. text: String, /// The port for the detached HTTP server. port: u16, } #[rpc] impl Consumer { /// Add a note through the generated import and return its count. async fn note(&self, p: NoteParams) -> Result { Ok(notes::add(notes::AddParams { text: p.text }).await?.count as usize) } /// Add a note, start a server, and inspect its control endpoint. async fn demo(&self, p: DemoParams) -> Result { let added = notes::add(notes::AddParams { text: p.text }).await?; eprintln!("{} notes", added.count); let pid = www::start(www::StartParams { port: p.port }) .detach() .await?; let control = www::control::connect(format!("/proc/{pid}/control")).await?; control.stats().await } /// Store and read a value through the boot service's fixed endpoint. async fn vault(&self) -> Result> { let vault = secrets::vault::connect("/run/secrets").await?; vault .put(secrets::PutParams { name: "example".into(), value: "hello".into(), }) .on_notify(|name, params| eprintln!("{name}: {params}")) .await?; vault .get(secrets::GetParams { name: "example".into(), }) .await } } /// Start the SDK transport for this plugin. fn main() { sausage_plugin::run(Consumer) } /// Tests check generated wire types without other plugins in the test world. #[cfg(test)] mod tests { use super::*; /// Generated params retain their wire field names. #[test] fn generated_params_use_text() { let value = sausage_plugin::serde_json::to_value(notes::AddParams { text: "milk".into(), }) .unwrap(); assert_eq!(value, sausage_plugin::serde_json::json!({"text":"milk"})); } /// A generated result decodes without another plugin in the test world. #[test] fn generated_result_decodes_count() { let added: notes::Added = sausage_plugin::serde_json::from_str(r#"{"count":2}"#).unwrap(); assert_eq!(added.count, 2); } }