#[macro_export]
macro_rules! lazy_env_parse {
($key:expr_2021, Option<String>) => {
std::sync::LazyLock::new(|| std::env::var($key).ok())
};
($key:expr_2021, $t:ty) => {
std::sync::LazyLock::new(|| {
std::env::var($key).ok().and_then(|s| s.parse::<$t>().ok()).unwrap_or_default()
})
};
($key:expr_2021, $t:ty, || $default:expr_2021) => {
std::sync::LazyLock::new(|| {
std::env::var($key).ok().and_then(|s| s.parse::<$t>().ok()).unwrap_or_else(|| $default)
})
};
($key:expr_2021, $t:ty, $default:expr_2021) => {
std::sync::LazyLock::new(|| {
std::env::var($key).ok().and_then(|s| s.parse::<$t>().ok()).unwrap_or($default)
})
};
(bytes, $key:expr_2021, $t:ty, || $default:expr_2021) => {
std::sync::LazyLock::new(|| {
std::env::var($key)
.ok()
.and_then(|s| {
use $crate::str::ParseBytes;
s.parse_bytes::<$t>().ok()
})
.unwrap_or_else(|| $default)
})
};
(bytes, $key:expr_2021, $t:ty, $default:expr_2021) => {
std::sync::LazyLock::new(|| {
std::env::var($key)
.ok()
.and_then(|s| {
use $crate::str::ParseBytes;
s.parse_bytes::<$t>().ok()
})
.unwrap_or($default)
})
};
(duration, $key:expr_2021, $t:ty, || $default:expr_2021) => {
std::sync::LazyLock::new(|| {
std::env::var($key)
.ok()
.and_then(|s| {
use $crate::str::ParseDuration;
s.parse_duration::<$t>().ok()
})
.unwrap_or_else(|| $default)
})
};
(duration, $key:expr_2021, $t:ty, $default:expr_2021) => {
std::sync::LazyLock::new(|| {
std::env::var($key)
.ok()
.and_then(|s| {
use $crate::str::ParseDuration;
s.parse_duration::<$t>().ok()
})
.unwrap_or($default)
})
};
}
#[macro_export]
macro_rules! map {
($($k:expr_2021 $(, if let $grant:pat = $check:expr_2021)? $(, if $guard:expr_2021)? => $v:expr_2021),* $(,)? $( => $x:expr_2021 )?) => {{
let mut pairs: ::std::vec::Vec<_> = ::std::vec::Vec::new();
$(pairs.extend($x.iter().map(|(k, v)| (k.clone(), v.clone())));)?
$( $(if let $grant = $check)? $(if $guard)? { pairs.push(($k, $v)); };)+
pairs.into_iter().collect::<$crate::VecMap<_, _>>()
}};
}
macro_rules! map_opt {
($x:ident as $opt:expr => $exp:expr) => {
match $opt {
Some($x) => Some($exp),
None => None,
}
};
}
#[macro_export]
macro_rules! mrg {
($m:expr_2021, $x:expr_2021) => {{
let mut pairs: ::std::vec::Vec<_> =
$m.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
pairs.extend($x.iter().map(|(k, v)| (k.clone(), v.clone())));
pairs.into_iter().collect::<$crate::VecMap<_, _>>()
}};
}
macro_rules! fail {
($($arg:tt)+) => {
return Err(::anyhow::Error::new($crate::err::Error::unreachable(format_args!($($arg)*))))
};
}
macro_rules! bytes {
($expression:expr_2021) => {
format!("{}\n", $expression).into_bytes()
};
}
macro_rules! yield_now {
() => {
if tokio::runtime::Handle::try_current().is_ok() {
tokio::task::consume_budget().await;
}
};
}
macro_rules! catch {
($txn:ident, $default:expr_2021) => {
match $default {
Err(e) => {
let _ = $txn.cancel().await;
return Err(e);
}
Ok(v) => v,
}
};
}
macro_rules! run {
($txn:ident, $default:expr_2021) => {
match $default {
Err(e) => {
let _ = $txn.cancel().await;
Err(e)
}
Ok(v) => match $txn.commit().await {
Err(e) => {
let _ = $txn.cancel().await;
Err(e)
}
Ok(_) => Ok(v),
},
}
};
}
#[cfg(test)]
mod test {
use crate::err::Error;
#[track_caller]
fn fail_func() -> Result<(), anyhow::Error> {
fail!("Reached unreachable code");
}
#[track_caller]
fn fail_func_args() -> Result<(), anyhow::Error> {
fail!("Found {} but expected {}", "test", "other");
}
#[test]
fn fail_literal() {
let line = line!();
let Ok(Error::Unreachable(msg)) = fail_func().unwrap_err().downcast() else {
panic!()
};
assert_eq!(
format!("surrealdb/core/src/mac/mod.rs:{}: Reached unreachable code", line + 1),
msg
);
}
#[test]
fn fail_call() {
let line = line!();
let Error::Unreachable(msg) = Error::unreachable("Reached unreachable code") else {
panic!()
};
assert_eq!(
format!("surrealdb/core/src/mac/mod.rs:{}: Reached unreachable code", line + 1),
msg
);
}
#[test]
fn fail_arguments() {
let line = line!();
let Ok(Error::Unreachable(msg)) = fail_func_args().unwrap_err().downcast() else {
panic!()
};
assert_eq!(
format!("surrealdb/core/src/mac/mod.rs:{}: Found test but expected other", line + 1),
msg
);
}
}