use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(test, derive(strum::EnumIter, strum::AsRefStr))]
pub enum ParseError {
BufferTooShort {
needed: usize,
available: usize,
field_num: i32,
},
ComplexTypeMismatch {
expected: &'static str,
actual: &'static str,
field_num: i32,
},
InvalidFieldNumber { field_num: i32 },
InvalidMapKeyType { field_num: i32 },
InvalidPackedFieldType { field_num: i32 },
InvalidUtf8 { field_num: i32 },
InvalidWireType(u8),
MaxNestingDepthExceeded { max: usize },
TruncatedVarint,
TypeMismatch {
expected: &'static str,
actual: &'static str,
field_num: i32,
},
UnknownTypeName { type_name: String },
UnsupportedGroupFieldType { field_num: i32 },
UnsupportedGroupWireType,
VarintTooLong,
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ParseError::BufferTooShort {
needed,
available,
field_num,
} => {
write!(
f,
"Field #{}: Input buffer too short: need {} bytes, have {}",
field_num, needed, available
)
}
ParseError::ComplexTypeMismatch {
expected,
actual,
field_num,
} => {
write!(
f,
"Field #{}: Complex type mismatch: expected {}, got {}",
field_num, expected, actual
)
}
ParseError::InvalidFieldNumber { field_num } => {
write!(
f,
"Field number {} is out of valid range (must be 1 to 536,870,911)",
field_num
)
}
ParseError::InvalidMapKeyType { field_num } => {
write!(
f,
"Field #{}: Invalid map key type (float, double, bytes are not allowed)",
field_num
)
}
ParseError::InvalidPackedFieldType { field_num } => {
write!(f, "Field #{}: Invalid packed field type", field_num)
}
ParseError::InvalidUtf8 { field_num } => {
write!(f, "Field #{}: Invalid UTF-8 in string field", field_num)
}
ParseError::InvalidWireType(wt) => write!(f, "Invalid wire type: {}", wt),
ParseError::MaxNestingDepthExceeded { max } => {
write!(
f,
"Message nesting depth exceeds maximum allowed limit of {} levels",
max
)
}
ParseError::TruncatedVarint => write!(f, "Truncated varint"),
ParseError::TypeMismatch {
expected,
actual,
field_num,
} => {
write!(
f,
"Field #{}: Type mismatch: expected {}, got {}",
field_num, expected, actual
)
}
ParseError::UnknownTypeName { type_name } => {
write!(f, "Unknown message type '{}' not in registry", type_name)
}
ParseError::UnsupportedGroupFieldType { field_num } => {
write!(f, "Deprecated group field type for field {}", field_num)
}
ParseError::UnsupportedGroupWireType => write!(f, "Group wire types are not supported"),
ParseError::VarintTooLong => write!(f, "Varint exceeds 10 bytes"),
}
}
}
impl std::error::Error for ParseError {}
pub type ParseResult<T> = Result<T, ParseError>;
#[cfg(test)]
mod tests {
use strum::IntoEnumIterator;
use super::ParseError;
#[test]
fn parse_error_variants_are_sorted() {
let names: Vec<String> = ParseError::iter().map(|e| e.as_ref().to_string()).collect();
let mut sorted = names.clone();
sorted.sort();
assert_eq!(
names, sorted,
"ParseError variants are not sorted alphabetically.\n\
Current order: {:?}\n\
Expected order: {:?}",
names, sorted
);
}
}