macro_rules! delegate {
($(#[$meta:meta])* $vis:vis fn $name:ident($($arg:ident: $ty:ty),* $(,)?) -> $ret:ty = $path:path) => {
$(#[$meta])*
#[doc = concat!("Delegates to [`", stringify!($path), "`].")]
#[doc = ""]
#[doc = "# Errors"]
#[doc = ""]
#[doc = "Returns a `QobuzApiError` if not authenticated or the API request fails."]
$vis fn $name(&self $(, $arg: $ty)*) -> Result<$ret, $crate::errors::QobuzApiError> {
let rt = Runtime::new()?;
rt.block_on($path(self $(, $arg)*))
}
};
}
macro_rules! retry_body {
($path:path, $rt:ident, $self:ident, first: ($($first_args:tt)*), retry: ($($retry_args:tt)*)) => {
{
let result = $rt.block_on($path($self, $($first_args)*));
match result {
Err($crate::errors::QobuzApiError::ApiErrorResponse { message, .. })
if message.contains("Invalid Request Signature") =>
{
info!(
path = stringify!($path),
"Signature invalid, refreshing credentials"
);
$crate::api::auth::refresh_app_credentials($self)?;
$rt.block_on($path($self, $($retry_args)*))
}
other => other,
}
}
};
}
macro_rules! delegate_with_retry {
($(#[$meta:meta])* $vis:vis fn $name:ident($($arg:ident: $ty:ty),* $(,)?) -> $ret:ty = $path:path) => {
delegate_with_retry!(
@inner $(#[$meta])* $vis fn $name -> $ret = $path,
fn_args: ($(, $arg: $ty)*),
first: ($($arg),*),
retry: ($($arg),*)
);
};
($(#[$meta:meta])* $vis:vis fn $name:ident($($arg:ident: $ty:ty),* $(,)?) -> $ret:ty = $path:path, cancel: $cancel_ty:ty) => {
delegate_with_retry!(
@inner $(#[$meta])* $vis fn $name -> $ret = $path,
fn_args: ($(, $arg: $ty)*, cancel: $cancel_ty),
first: ($($arg),*, cancel.clone()),
retry: ($($arg),*, cancel)
);
};
(@inner $(#[$meta:meta])* $vis:vis fn $name:ident -> $ret:ty = $path:path, fn_args: ($($fn_args:tt)*), first: ($($first:tt)*), retry: ($($retry:tt)*)) => {
$(#[$meta])*
#[doc = concat!("Delegates to [`", stringify!($path), "`] with auto-refresh on signature errors.")]
#[doc = ""]
#[doc = "# Errors"]
#[doc = ""]
#[doc = "Returns a `QobuzApiError` if not authenticated, the API request fails, or refresh fails."]
$vis fn $name(&mut self $($fn_args)*) -> Result<$ret, $crate::errors::QobuzApiError> {
let rt = Runtime::new()?;
retry_body!($path, rt, self, first: ($($first)*), retry: ($($retry)*))
}
};
}
macro_rules! delegate_with_retry_cancellable {
($(#[$meta:meta])* $vis:vis fn $name:ident($($arg:ident: $ty:ty),* $(,)?) -> $ret:ty = $path:path, cancel: $cancel_ty:ty) => {
delegate_with_retry!($(#[$meta])* $vis fn $name($($arg: $ty),*) -> $ret = $path, cancel: $cancel_ty);
};
}