use std::time::{Duration, SystemTime, UNIX_EPOCH};
use macula_rust::{
cbor::Value,
connection::{self, BoxFuture, CallHandler},
frame::AdvertiseSpec,
identity::KeyPair,
transport::Trust,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let provider_identity = KeyPair::generate_with_default_puzzle();
let caller_identity = KeyPair::generate_with_default_puzzle();
let mut provider_session = connection::connect(
"station-de-frankfurt.macula.io",
4433,
Trust::WebPki,
&provider_identity,
)
.await?;
let mut caller_session = connection::connect(
"station-de-frankfurt.macula.io",
4433,
Trust::WebPki,
&caller_identity,
)
.await?;
let realm = [0u8; 32];
let procedure = format!(
"macula_rust.quickstart_echo.{}",
SystemTime::now().duration_since(UNIX_EPOCH)?.as_nanos()
);
let advertise_spec = AdvertiseSpec::new(realm, procedure.clone(), provider_identity.node_id());
provider_session
.advertise(&advertise_spec, &provider_identity)
.await?;
tokio::time::sleep(Duration::from_millis(500)).await;
let target_procedure = procedure.clone();
let lookup = move |_realm: &[u8; 32], proc: &str| -> Option<CallHandler> {
if proc != target_procedure {
return None;
}
let handler: CallHandler = std::sync::Arc::new(|payload: Value| {
Box::pin(async move { Ok(payload) }) as BoxFuture<'static, Result<Value, String>>
});
Some(handler)
};
let serve_task = tokio::spawn(async move {
let result = provider_session
.serve_one_call(lookup, &provider_identity, Duration::from_secs(10))
.await;
provider_session
.close(
"normal",
Some("quickstart provider done"),
&provider_identity,
)
.await;
result
});
let now_ms = SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis() as i128;
let response = caller_session
.call(
&procedure,
realm,
Value::Text("hello".into()),
now_ms + 5_000, &caller_identity,
Duration::from_secs(5),
)
.await?;
serve_task.await??;
caller_session
.close("normal", Some("quickstart caller done"), &caller_identity)
.await;
println!("{response:?}");
Ok(())
}