use super::types::OxiGdalError;
#[cfg(not(feature = "std"))]
use alloc::collections::BTreeMap as HashMap;
#[cfg(not(feature = "std"))]
use alloc::string::String;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::collections::HashMap;
#[cfg(feature = "std")]
use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct ErrorContext {
pub category: &'static str,
pub details: Vec<(String, String)>,
#[cfg(feature = "std")]
pub file_path: Option<PathBuf>,
pub operation: Option<String>,
pub parameters: HashMap<String, String>,
pub custom_suggestion: Option<String>,
}
impl ErrorContext {
pub fn new(category: &'static str) -> Self {
Self {
category,
details: Vec::new(),
#[cfg(feature = "std")]
file_path: None,
operation: None,
parameters: HashMap::new(),
custom_suggestion: None,
}
}
pub fn with_detail(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.details.push((key.into(), value.into()));
self
}
#[cfg(feature = "std")]
pub fn with_path(mut self, path: PathBuf) -> Self {
self.file_path = Some(path);
self
}
pub fn with_operation(mut self, operation: String) -> Self {
self.operation = Some(operation);
self
}
pub fn with_parameter(mut self, key: String, value: String) -> Self {
self.parameters.insert(key, value);
self
}
pub fn with_custom_suggestion(mut self, suggestion: String) -> Self {
self.custom_suggestion = Some(suggestion);
self
}
}
#[derive(Debug)]
pub struct ErrorBuilder {
error: OxiGdalError,
#[cfg(feature = "std")]
path: Option<PathBuf>,
operation: Option<String>,
parameters: HashMap<String, String>,
custom_suggestion: Option<String>,
}
impl ErrorBuilder {
pub fn new(error: OxiGdalError) -> Self {
Self {
error,
#[cfg(feature = "std")]
path: None,
operation: None,
parameters: HashMap::new(),
custom_suggestion: None,
}
}
#[cfg(feature = "std")]
pub fn with_path(mut self, path: impl AsRef<Path>) -> Self {
self.path = Some(path.as_ref().to_path_buf());
self
}
pub fn with_operation(mut self, operation: impl Into<String>) -> Self {
self.operation = Some(operation.into());
self
}
pub fn with_parameter(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.parameters.insert(key.into(), value.into());
self
}
pub fn with_suggestion(mut self, suggestion: impl Into<String>) -> Self {
self.custom_suggestion = Some(suggestion.into());
self
}
pub fn build(self) -> OxiGdalError {
self.error
}
pub fn into_error(self) -> OxiGdalError {
self.error
}
pub fn error(&self) -> &OxiGdalError {
&self.error
}
#[cfg(feature = "std")]
pub fn file_path(&self) -> Option<&Path> {
self.path.as_deref()
}
pub fn operation_name(&self) -> Option<&str> {
self.operation.as_deref()
}
pub fn parameters(&self) -> &HashMap<String, String> {
&self.parameters
}
pub fn custom_suggestion(&self) -> Option<&str> {
self.custom_suggestion.as_deref()
}
pub fn suggestion(&self) -> Option<String> {
if let Some(ref custom) = self.custom_suggestion {
Some(custom.clone())
} else {
self.error.suggestion().map(|s| s.to_string())
}
}
pub fn build_context(&self) -> ErrorContext {
let mut ctx = self.error.context();
#[cfg(feature = "std")]
if let Some(ref path) = self.path {
ctx = ctx.with_path(path.clone());
}
if let Some(ref op) = self.operation {
ctx = ctx.with_operation(op.clone());
}
for (key, value) in &self.parameters {
ctx = ctx.with_parameter(key.clone(), value.clone());
}
if let Some(ref suggestion) = self.custom_suggestion {
ctx = ctx.with_custom_suggestion(suggestion.clone());
}
ctx
}
}
impl From<ErrorBuilder> for OxiGdalError {
fn from(builder: ErrorBuilder) -> Self {
builder.error
}
}