//! 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> { 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::(&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(()) }