#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/doc_assets/adaptor.svg"))]
use std::{fmt, pin::Pin};
pub use prosa_macros::Adaptor;
#[doc = simple_mermaid::mermaid!("diagrams/adaptor.mmd")]
pub trait Adaptor {
fn reload_config(&self, _config: Option<&config::Config>) -> Result<(), config::ConfigError> {
Ok(())
}
fn terminate(&self);
}
pub enum MaybeAsync<T> {
Ready(T),
Future(Pin<Box<dyn Future<Output = T> + Send>>),
}
impl<T> From<T> for MaybeAsync<T> {
fn from(value: T) -> Self {
MaybeAsync::Ready(value)
}
}
impl<T> From<Pin<Box<dyn Future<Output = T> + Send>>> for MaybeAsync<T> {
fn from(future: Pin<Box<dyn Future<Output = T> + Send>>) -> Self {
MaybeAsync::Future(future)
}
}
impl<T> fmt::Debug for MaybeAsync<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"MaybeAsync::{}",
match self {
MaybeAsync::Ready(_) => "Ready",
MaybeAsync::Future(_) => "Future",
}
)
}
}
#[macro_export]
macro_rules! maybe_async {
(async move $block:expr) => {
MaybeAsync::Future(Box::pin(async move { $block }))
};
(async $block:expr) => {
MaybeAsync::Future(Box::pin(async { $block }))
};
($expr:expr) => {
MaybeAsync::Ready($expr)
};
}
#[cfg(test)]
mod tests {
extern crate self as prosa;
use crate::core::adaptor::MaybeAsync;
const MAYBE_VAL: &str = "value";
fn test_ready(macro_def: bool) -> MaybeAsync<String> {
if macro_def {
maybe_async!(MAYBE_VAL.to_string())
} else {
MaybeAsync::Ready(MAYBE_VAL.to_string())
}
}
fn test_future(macro_def: bool) -> MaybeAsync<String> {
if macro_def {
maybe_async!(async MAYBE_VAL.to_string())
} else {
MaybeAsync::Future(Box::pin(async { MAYBE_VAL.to_string() }))
}
}
#[tokio::test]
async fn test_maybe_async() {
if let MaybeAsync::Ready(val) = test_ready(false) {
assert_eq!(val, MAYBE_VAL);
} else {
panic!("Expected MaybeAsync::Ready, got something else");
}
if let MaybeAsync::Ready(val) = test_ready(true) {
assert_eq!(val, MAYBE_VAL);
} else {
panic!("Expected MaybeAsync::Ready, got something else");
}
if let MaybeAsync::Future(val) = test_future(false) {
assert_eq!(val.await, MAYBE_VAL);
} else {
panic!("Expected MaybeAsync::Future, got something else");
}
if let MaybeAsync::Future(val) = test_future(true) {
assert_eq!(val.await, MAYBE_VAL);
} else {
panic!("Expected MaybeAsync::Future, got something else");
}
}
}