use super::types::OxiGdalError;
#[cfg(not(feature = "std"))]
use alloc::string::String;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
#[macro_export]
macro_rules! ensure {
($cond:expr, $err:expr) => {
if !($cond) {
return Err($crate::error::OxiGdalError::$err.into());
}
};
($cond:expr, $err:ident { $($field:ident: $value:expr),* $(,)? }) => {
if !($cond) {
return Err($crate::error::OxiGdalError::$err {
$($field: $value),*
}.into());
}
};
}
pub trait ResultExt<T> {
fn context(self, msg: impl Into<String>) -> crate::error::Result<T>;
fn with_context<F>(self, f: F) -> crate::error::Result<T>
where
F: FnOnce() -> String;
}
impl<T> ResultExt<T> for crate::error::Result<T> {
fn context(self, msg: impl Into<String>) -> crate::error::Result<T> {
self.map_err(|_| OxiGdalError::Internal {
message: msg.into(),
})
}
fn with_context<F>(self, f: F) -> crate::error::Result<T>
where
F: FnOnce() -> String,
{
self.map_err(|_| OxiGdalError::Internal { message: f() })
}
}
#[derive(Debug)]
pub struct ErrorAggregator {
errors: Vec<OxiGdalError>,
}
impl ErrorAggregator {
pub fn new() -> Self {
Self { errors: Vec::new() }
}
pub fn add(&mut self, error: OxiGdalError) {
self.errors.push(error);
}
pub fn add_result<T>(&mut self, result: crate::error::Result<T>) -> Option<T> {
match result {
Ok(value) => Some(value),
Err(error) => {
self.add(error);
None
}
}
}
pub fn has_errors(&self) -> bool {
!self.errors.is_empty()
}
pub fn count(&self) -> usize {
self.errors.len()
}
pub fn into_result(self) -> crate::error::Result<()> {
if self.errors.is_empty() {
Ok(())
} else {
let count = self.errors.len();
let first = &self.errors[0];
Err(OxiGdalError::Internal {
message: format!(
"Multiple errors occurred ({} total). First error: {}",
count, first
),
})
}
}
pub fn into_errors(self) -> Vec<OxiGdalError> {
self.errors
}
}
impl Default for ErrorAggregator {
fn default() -> Self {
Self::new()
}
}