macro_rules! impl_builder {
($n:ident: $t:ty,) => {
paste::paste! {
impl_builder! { $n: $t as [<with_ $n>](), }
}
};
($n:ident: $t:ty as $m:ident(),) => {
#[must_use]
pub fn $m(mut self, value: $t) -> Self {
self.$n = value;
self
}
};
}
pub(crate) use impl_builder;
macro_rules! decl_call {
($name:ident($($n:ident: $t:ty $(,)?)*) -> $result:ty, { $($opt_n:ident: $opt_t:ty $(as $opt_m:ident())?,)* }) => {
pub struct $name<T: SessionTrait> {
pub(crate) session: T,
$($n: $t,)*
$($opt_n: $opt_t,)*
}
paste::paste! {
impl SessionAsync {
#[must_use]
pub fn [<$name:snake>](&self, $($n:$t,)*) -> $name<Self> {
$name {
session: self.clone(),
$($n,)*
$($opt_n: Default::default(),)*
}
}
}
impl Session {
#[must_use]
pub fn [<$name:snake>](&self, $($n:$t,)*) -> $name<Self> {
$name {
session: self.clone(),
$($n,)*
$($opt_n: Default::default(),)*
}
}
}
}
impl IntoFuture for $name<SessionAsync> {
type IntoFuture = Pin<Box<dyn Future<Output = Result<$result, CallError>> + Send>>;
type Output = <Self::IntoFuture as Future>::Output;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move { self.call_async().await })
}
}
impl $name<Session> {
pub fn call(self) -> Result<$result, CallError> {
self.session.clone().run_async(|_| self.call_async())
}
}
impl<T> $name<T>
where
T: SessionTrait,
{
$(
impl_builder!{ $opt_n: $opt_t $(as $opt_m())?, }
)*
}
};
}
pub(crate) use decl_call;
macro_rules! opt_impl_builder_atapi {
($n:ident: $t:ty,) => {
paste::paste! {
opt_impl_builder_atapi! { $n: $t as [<with_$n>](), }
}
};
($n:ident: $t:ty as $m:ident(),) => {
paste::paste! {
#[must_use]
pub fn $m(mut self, value: $t) -> Self {
self.msg.[<pack_ $n>](value);
self
}
}
};
}
pub(crate) use opt_impl_builder_atapi;
macro_rules! decl_call_atapi {
($name:ident($($n:ident: $t:ty $(,)?)*) -> $result:ty, { $($opt_n:ident: $opt_t:ty $(as $m:ident())?,)* }) => {
pub struct $name<T: SessionTrait> {
pub(crate) session: T,
pub(crate) msg: HGTPMessage,
}
paste::paste! {
impl SessionAsync {
#[must_use]
pub fn [<$name:snake>](&self, $($n:$t,)*) -> $name<Self> {
#[allow(unused_mut)]
let mut msg = HGTPMessage::default();
$(
msg.[<pack_ $n>]($n);
)*
$name {
session: self.clone(),
msg,
}
}
}
impl Session {
#[must_use]
pub fn [<$name:snake>](&self, $($n:$t,)*) -> $name<Self> {
#[allow(unused_mut)]
let mut msg = HGTPMessage::default();
$(
msg.[<pack_ $n>]($n);
)*
$name {
session: self.clone(),
msg,
}
}
}
}
impl IntoFuture for $name<SessionAsync> {
type IntoFuture = Pin<Box<dyn Future<Output = Result<$result, CallError>> + Send>>;
type Output = <Self::IntoFuture as Future>::Output;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move { self.call_async().await })
}
}
impl $name<Session> {
pub fn call(self) -> Result<$result, CallError> {
self.session.clone().run_async(|_| self.call_async())
}
}
impl<T> $name<T>
where
T: SessionTrait,
{
$(
opt_impl_builder_atapi!{ $opt_n: $opt_t $(as $m())?, }
)*
}
};
}
pub(crate) use decl_call_atapi;