use serde::ser::Error as SerdeError;
use thiserror::Error;
fn format_nested_field_error(path: &[String], failed_at_index: Option<usize>) -> String {
let path_str = path.join(".");
match failed_at_index {
Some(idx) if idx < path.len() => {
format!(
"Nested field path '{}' not found (failed at segment {}: '{}')",
path_str, idx, path[idx]
)
}
_ => format!("Nested field path '{}' not found", path_str),
}
}
#[derive(Error, Debug, PartialEq)]
pub enum EvaluateError {
#[error("Field '{field_name}' not found in the struct")]
FieldNotFound {
field_name: String,
},
#[error("{}", format_nested_field_error(path, *failed_at_index))]
NestedFieldNotFound {
path: Vec<String>,
failed_at_index: Option<usize>,
},
#[error("Cannot traverse non-struct type at path segment {index}: '{segment}'")]
NotAStruct {
segment: String,
index: usize,
},
#[error("Unsupported type for scalar extraction: {type_name}")]
UnsupportedType {
type_name: &'static str,
},
#[error("Unsupported variant type for scalar extraction: {variant_type}")]
UnsupportedVariant {
variant_type: &'static str,
},
#[error("Invalid field path provided: {0}")]
InvalidPath(String),
#[error("Serialization error: {message}")]
SerializationError {
message: String,
},
}
impl SerdeError for EvaluateError {
fn custom<T>(msg: T) -> Self
where
T: std::fmt::Display,
{
EvaluateError::SerializationError {
message: msg.to_string(),
}
}
}