use crate::Context;
use core::fmt::Display;
use minicbor::Encode;
use ockam_core::api::{assert_request_match, RequestBuilder};
use ockam_core::compat::sync::Arc;
use ockam_core::compat::vec::Vec;
use ockam_core::{
Address, AllowAll, AllowOnwardAddress, LocalInfo, Mailbox, Mailboxes, Result, Route,
};
pub async fn request<T, R>(
ctx: &Context,
label: &str,
struct_name: impl Into<Option<&str>>,
route: R,
req: RequestBuilder<'_, T>,
) -> Result<Vec<u8>>
where
T: Encode<()>,
R: Into<Route> + Display,
{
let mut buf = Vec::new();
req.encode(&mut buf)?;
assert_request_match(struct_name, &buf);
trace! {
target: "ockam_api",
id = %req.header().id(),
method = ?req.header().method(),
path = %req.header().path(),
body = %req.header().has_body(),
"-> {label}"
};
let vec: Vec<u8> = ctx.send_and_receive(route, buf).await?;
Ok(vec)
}
pub async fn request_with_local_info<T, R>(
ctx: &Context,
label: &str,
struct_name: impl Into<Option<&str>>,
route: R,
req: RequestBuilder<'_, T>,
) -> Result<(Vec<u8>, Vec<LocalInfo>)>
where
T: Encode<()>,
R: Into<Route> + Display,
{
let route = route.into();
let mut buf = Vec::new();
req.encode(&mut buf)?;
assert_request_match(struct_name, &buf);
trace! {
target: "ockam_api",
id = %req.header().id(),
method = ?req.header().method(),
path = %req.header().path(),
body = %req.header().has_body(),
"-> {label}"
};
let next = route.next()?.clone();
let mailboxes = Mailboxes::new(
Mailbox::new(
Address::random_tagged("api.request_with_local_info"),
Arc::new(AllowAll), Arc::new(AllowOnwardAddress(next)),
),
vec![],
);
let mut child_ctx = ctx.new_detached_with_mailboxes(mailboxes).await?;
child_ctx.send(route, buf).await?;
let resp = child_ctx.receive::<Vec<u8>>().await?.take();
let local_info = resp.local_message().local_info().to_vec();
let body = resp.body();
Ok((body, local_info))
}