Skip to main content

nros/guide/
services.rs

1//! # Service Calls and Promise API
2//!
3//! `client.call(&request)` returns a `Promise` immediately — no blocking.
4//! The reply can be polled with `try_recv()` or `.await`ed.
5//!
6//! ## Sync polling (no async runtime)
7//!
8//! Drive I/O with `spin_once()` while polling the promise:
9//!
10//! ```ignore
11//! use nros::prelude::*;
12//! use example_interfaces::srv::{AddTwoInts, AddTwoIntsRequest};
13//!
14//! let config = ExecutorConfig::from_env().node_name("client");
15//! let mut executor: Executor = Executor::open(&config)?;
16//! let mut node = executor.create_node("client")?;
17//! let mut client = node.create_client::<AddTwoInts>("/add_two_ints")?;
18//!
19//! let mut promise = client.call(&AddTwoIntsRequest { a: 1, b: 2 })?;
20//!
21//! let reply = loop {
22//!     executor.spin_once(core::time::Duration::from_millis(10));
23//!     if let Ok(Some(reply)) = promise.try_recv() {
24//!         break reply;
25//!     }
26//! };
27//! println!("sum = {}", reply.sum);
28//! ```
29//!
30//! ## Async (background spin task)
31//!
32//! Spawn `spin_async()` as a background task, then `.await` promises:
33//!
34//! ```ignore
35//! use nros::prelude::*;
36//! use example_interfaces::srv::{AddTwoInts, AddTwoIntsRequest};
37//!
38//! #[tokio::main(flavor = "current_thread")]
39//! async fn main() {
40//!     let config = ExecutorConfig::from_env().node_name("client");
41//!     let mut executor: Executor = Executor::open(&config).unwrap();
42//!     let mut client = {
43//!         let mut node = executor.create_node("client").unwrap();
44//!         node.create_client::<AddTwoInts>("/add_two_ints").unwrap()
45//!     };
46//!
47//!     let local = tokio::task::LocalSet::new();
48//!     local.run_until(async move {
49//!         tokio::task::spawn_local(async move {
50//!             executor.spin_async().await;
51//!         });
52//!         let reply = client.call(&AddTwoIntsRequest { a: 1, b: 2 })
53//!             .unwrap().await.unwrap();
54//!         println!("sum = {}", reply.sum);
55//!     }).await;
56//! }
57//! ```
58//!
59//! The Promise and `spin_async()` APIs use only `core::future` — no
60//! external runtime dependency.  They work on `no_std`/`no_alloc` targets.
61//! For async combinators (`select`, `join`), add `embassy-futures`.
62//!
63//! See `examples/native/rust/service-client-async/` (tokio) for a complete
64//! working example. The Zephyr Embassy variant was dropped 2026-06-02 per
65//! Phase 212.M-F.5 — pending an async-`Node` trait decision.