Files
unshell/examples/protocol/remote_shell_single_endpoint.rs
T
2026-04-26 15:36:45 -06:00

48 lines
2.0 KiB
Rust

//! Smallest in-process `remote_shell` declaration example.
//!
//! This example hosts exactly one protocol endpoint with exactly one leaf and performs a local
//! introspection request against that leaf. The important detail is that the endpoint metadata is
//! taken from `remote_shell::endpoint::RemoteShellEndpoint::protocol_leaf_spec()`, which is
//! generated by the `leaf!` declaration in `unshell-leaves/src/remote_shell/mod.rs`.
//!
//! It does not open any sockets or spawn a shell process, so it is the easiest place to verify
//! that the shared compile-time leaf declaration and the generated endpoint host metadata line up.
use std::error::Error;
use unshell::create_endpoint;
use unshell::leaves::remote_shell;
use unshell::protocol::tree::{Endpoint, EndpointOutcome, LocalEvent, ProtocolEndpoint};
use unshell::protocol::{INTROSPECTION_PROCEDURE_ID, LeafIntrospection};
fn main() -> Result<(), Box<dyn Error>> {
let mut endpoint: ProtocolEndpoint =
create_endpoint!("agent", remote_shell::endpoint::RemoteShell::default());
let leaf_spec = remote_shell::endpoint::RemoteShell::protocol_leaf_spec();
let hook_id = endpoint.allocate_hook_id();
let outcome = endpoint.send_call(
Vec::new(),
Some(remote_shell::endpoint::RemoteShell::protocol_leaf_name()),
INTROSPECTION_PROCEDURE_ID,
Some(hook_id),
Vec::new(),
)?;
let EndpointOutcome::Local(LocalEvent::Data { message, .. }) = outcome else {
return Err("expected one local introspection response".into());
};
let payload = unshell::protocol::tree::decode_call_input::<LeafIntrospection>(&message.data)?;
println!(
"remote-shell examples normally listen on {}",
remote_shell::endpoint::LISTEN_ADDR
);
println!("endpoint id: {:?}", endpoint.local_id());
println!("endpoint path: {:?}", endpoint.path());
println!("declared leaf: {}", leaf_spec.name);
println!("leaf: {}", payload.leaf_name);
println!("procedures: {:?}", payload.procedures);
Ok(())
}