use std::fmt;
#[derive(Debug)]
#[non_exhaustive]
pub enum SerdeError {
#[non_exhaustive]
TypeMismatch {
message: String,
},
#[non_exhaustive]
MissingMember {
member_name: String,
},
#[non_exhaustive]
UnknownMember {
member_name: String,
},
#[non_exhaustive]
InvalidInput {
message: String,
},
#[non_exhaustive]
UnsupportedOperation {
message: String,
},
#[non_exhaustive]
WriteFailed {
message: String,
},
#[non_exhaustive]
NumericCoercionOverflow {
target: String,
value: String,
},
#[non_exhaustive]
NumericCoercionLossy {
target: String,
value: String,
},
#[non_exhaustive]
BlobDecodeFailed {
message: String,
},
#[non_exhaustive]
TimestampParseFailed {
message: String,
},
#[non_exhaustive]
Custom {
message: String,
},
}
impl fmt::Display for SerdeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SerdeError::TypeMismatch { message } => write!(f, "type mismatch: {message}"),
SerdeError::MissingMember { member_name } => {
write!(f, "missing required member: {member_name}")
}
SerdeError::UnknownMember { member_name } => {
write!(f, "unknown member: {member_name}")
}
SerdeError::InvalidInput { message } => write!(f, "invalid input: {message}"),
SerdeError::UnsupportedOperation { message } => {
write!(f, "unsupported operation: {message}")
}
SerdeError::WriteFailed { message } => write!(f, "write failed: {message}"),
SerdeError::NumericCoercionOverflow { target, value } => {
write!(f, "numeric value {value} out of range for {target}")
}
SerdeError::NumericCoercionLossy { target, value } => {
write!(
f,
"numeric value {value} cannot be coerced to {target} without precision loss"
)
}
SerdeError::BlobDecodeFailed { message } => write!(f, "blob decode failed: {message}"),
SerdeError::TimestampParseFailed { message } => {
write!(f, "timestamp parse failed: {message}")
}
SerdeError::Custom { message } => f.write_str(message),
}
}
}
impl std::error::Error for SerdeError {}
impl SerdeError {
pub fn type_mismatch(message: impl Into<String>) -> Self {
SerdeError::TypeMismatch {
message: message.into(),
}
}
pub fn missing_member(member_name: impl Into<String>) -> Self {
SerdeError::MissingMember {
member_name: member_name.into(),
}
}
pub fn unknown_member(member_name: impl Into<String>) -> Self {
SerdeError::UnknownMember {
member_name: member_name.into(),
}
}
pub fn invalid_input(message: impl Into<String>) -> Self {
SerdeError::InvalidInput {
message: message.into(),
}
}
pub fn unsupported(message: impl Into<String>) -> Self {
SerdeError::UnsupportedOperation {
message: message.into(),
}
}
pub fn write_failed(message: impl Into<String>) -> Self {
SerdeError::WriteFailed {
message: message.into(),
}
}
pub fn numeric_coercion_overflow(target: impl Into<String>, value: impl Into<String>) -> Self {
SerdeError::NumericCoercionOverflow {
target: target.into(),
value: value.into(),
}
}
pub fn numeric_coercion_lossy(target: impl Into<String>, value: impl Into<String>) -> Self {
SerdeError::NumericCoercionLossy {
target: target.into(),
value: value.into(),
}
}
pub fn blob_decode_failed(message: impl Into<String>) -> Self {
SerdeError::BlobDecodeFailed {
message: message.into(),
}
}
pub fn timestamp_parse_failed(message: impl Into<String>) -> Self {
SerdeError::TimestampParseFailed {
message: message.into(),
}
}
pub fn custom(message: impl Into<String>) -> Self {
SerdeError::Custom {
message: message.into(),
}
}
}
impl From<aws_smithy_types::DocumentError> for SerdeError {
fn from(err: aws_smithy_types::DocumentError) -> Self {
use aws_smithy_types::DocumentError as DE;
match err {
DE::TypeMismatch { message, .. } => SerdeError::type_mismatch(message),
DE::NumericCoercionOverflow { target, value, .. } => {
SerdeError::numeric_coercion_overflow(target, value)
}
DE::InvalidInput { message, .. } => SerdeError::invalid_input(message),
DE::UnsupportedOperation { message, .. } => SerdeError::unsupported(message),
DE::Custom { message, .. } => SerdeError::custom(message),
other => SerdeError::custom(format!("{other}")),
}
}
}