use std::{
io,
string::{FromUtf16Error, FromUtf8Error},
};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum DeserializeError {
#[error("Invalid header: {0}")]
InvalidHeader(Box<str>),
#[error("Invalid value size, expected {0} got {1} at position {2:#x}")]
InvalidValueSize(u64, u64, u64),
#[error("Invalid string size {0} at position {1:#x}")]
InvalidString(i32, u64),
#[error("Invalid string terminator {0} at position {1:#x}")]
InvalidStringTerminator(u16, u64),
#[error("Invalid boolean value {0} at position {1:#x}")]
InvalidBoolean(u32, u64),
#[error("Missing hint for struct {0} at path {1} at position {2:#x}")]
MissingHint(Box<str>, Box<str>, u64),
#[error("Missing argument: {0} at position {1:#x}")]
MissingArgument(Box<str>, u64),
#[error("Invalid property {0} at position {1:#x}")]
InvalidProperty(Box<str>, u64),
#[error("No discriminant in enum `{0}` matches the value `{1}` at position {2:#x}")]
InvalidEnumValue(Box<str>, i8, u64),
#[error("Unexpected array_index value {0} at position {1:#x}")]
InvalidArrayIndex(u32, u64),
#[error("Unexpected terminator value {0} at position {1:#x}")]
InvalidTerminator(u8, u64),
#[error("Invalid UTF-16 string at position {1:#x}")]
FromUtf16Error(#[source] FromUtf16Error, u64),
#[error("Invalid UTF-8 string at position {1:#x}")]
FromUtf8Error(#[source] FromUtf8Error, u64),
}
impl DeserializeError {
#[inline]
pub fn missing_argument<A, S>(argument_name: A, stream: &mut S) -> Self
where
A: Into<Box<str>>,
S: io::Seek,
{
let position = stream.stream_position().unwrap_or_default();
Self::MissingArgument(argument_name.into(), position)
}
#[inline]
pub fn invalid_property<R, S>(reason: R, stream: &mut S) -> Self
where
R: Into<Box<str>>,
S: io::Seek,
{
let position = stream.stream_position().unwrap_or_default();
Self::InvalidProperty(reason.into(), position)
}
#[inline]
pub fn invalid_enum_value<N, S>(name: N, value: i8, stream: &mut S) -> Self
where
N: Into<Box<str>>,
S: io::Seek,
{
let position = stream.stream_position().unwrap_or_default();
Self::InvalidEnumValue(name.into(), value, position)
}
}
#[derive(Error, Debug)]
pub enum SerializeError {
#[error("Invalid value {0}")]
InvalidValue(Box<str>),
#[error("Struct {0} missing field {1}")]
StructMissingField(Box<str>, Box<str>),
}
impl SerializeError {
pub fn invalid_value<M>(msg: M) -> Self
where
M: Into<Box<str>>,
{
Self::InvalidValue(msg.into())
}
pub fn struct_missing_field<T, M>(type_name: T, missing_field: M) -> Self
where
T: Into<Box<str>>,
M: Into<Box<str>>,
{
Self::StructMissingField(type_name.into(), missing_field.into())
}
}
#[derive(Error, Debug)]
pub enum Error {
#[error(transparent)]
Deserialize(#[from] DeserializeError),
#[error(transparent)]
Serialize(#[from] SerializeError),
#[error(transparent)]
Io(#[from] io::Error),
}