Skip to main content

wincode/
error.rs

1//! Error types and helpers.
2use {crate::io, core::str::Utf8Error, thiserror::Error};
3
4#[derive(Error, Debug)]
5pub enum Error {
6    #[error(transparent)]
7    WriteError(#[from] WriteError),
8    #[error(transparent)]
9    ReadError(#[from] ReadError),
10}
11
12#[derive(Error, Debug)]
13pub enum WriteError {
14    #[error(transparent)]
15    Io(#[from] io::WriteError),
16    #[error(transparent)]
17    InvalidUtf8Encoding(#[from] Utf8Error),
18    #[error("Sequence length would overflow length encoding scheme: {0}")]
19    LengthEncodingOverflow(&'static str),
20    #[error(
21        "Encoded sequence length exceeded preallocation limit of {limit} bytes (needed {needed} \
22         bytes)"
23    )]
24    PreallocationSizeLimit { needed: usize, limit: usize },
25    #[error("Tag value would overflow tag encoding scheme: {0}")]
26    TagEncodingOverflow(&'static str),
27    #[error("Custom error: {0}")]
28    Custom(&'static str),
29}
30
31#[derive(Error, Debug)]
32pub enum ReadError {
33    #[error(transparent)]
34    Io(#[from] io::ReadError),
35    #[error(transparent)]
36    InvalidUtf8Encoding(#[from] Utf8Error),
37    #[error("Decoded UTF-8 value {0} is not a valid character")]
38    InvalidUtf8Code(u32),
39    #[error("Could not cast integer type to pointer sized type")]
40    PointerSizedReadError,
41    #[error(
42        "Encoded sequence length exceeded preallocation limit of {limit} bytes (needed {needed} \
43         bytes)"
44    )]
45    PreallocationSizeLimit { needed: usize, limit: usize },
46    #[error("Invalid tag encoding: {0}")]
47    InvalidTagEncoding(usize),
48    #[error("Invalid bool encoding: {0}")]
49    InvalidBoolEncoding(u8),
50    #[error("Sequence length would overflow length encoding scheme: {0}")]
51    LengthEncodingOverflow(&'static str),
52    #[error("Invalid value: {0}")]
53    InvalidValue(&'static str),
54    #[error("Invalid char lead: {0}")]
55    InvalidCharLead(u8),
56    #[error("Trailing bytes remain after deserialization")]
57    TrailingBytes,
58    #[error("Custom error: {0}")]
59    Custom(&'static str),
60    #[error("Zero-copy read would be unaligned")]
61    UnalignedPointerRead,
62    #[error("Tag value would overflow tag encoding scheme: {0}")]
63    TagEncodingOverflow(&'static str),
64}
65
66pub struct PreallocationError {
67    needed: usize,
68    limit: usize,
69}
70
71pub struct TagEncodingOverflow(pub &'static str);
72
73pub type Result<T> = core::result::Result<T, Error>;
74pub type WriteResult<T> = core::result::Result<T, WriteError>;
75pub type ReadResult<T> = core::result::Result<T, ReadError>;
76
77#[cold]
78pub const fn unaligned_pointer_read() -> ReadError {
79    ReadError::UnalignedPointerRead
80}
81
82#[cold]
83pub const fn preallocation_size_limit(needed: usize, limit: usize) -> PreallocationError {
84    PreallocationError { needed, limit }
85}
86
87#[cold]
88pub const fn read_length_encoding_overflow(max_length: &'static str) -> ReadError {
89    ReadError::LengthEncodingOverflow(max_length)
90}
91
92#[cold]
93pub const fn write_length_encoding_overflow(max_length: &'static str) -> WriteError {
94    WriteError::LengthEncodingOverflow(max_length)
95}
96
97#[cold]
98pub const fn pointer_sized_decode_error() -> ReadError {
99    ReadError::PointerSizedReadError
100}
101
102#[cold]
103pub const fn invalid_bool_encoding(byte: u8) -> ReadError {
104    ReadError::InvalidBoolEncoding(byte)
105}
106
107#[cold]
108pub const fn invalid_tag_encoding(tag: usize) -> ReadError {
109    ReadError::InvalidTagEncoding(tag)
110}
111
112#[cold]
113pub const fn invalid_utf8_encoding(error: Utf8Error) -> ReadError {
114    ReadError::InvalidUtf8Encoding(error)
115}
116
117#[cold]
118pub const fn invalid_char_lead(val: u8) -> ReadError {
119    ReadError::InvalidCharLead(val)
120}
121
122#[cold]
123pub const fn invalid_value(msg: &'static str) -> ReadError {
124    ReadError::InvalidValue(msg)
125}
126
127#[cold]
128pub const fn trailing_bytes() -> ReadError {
129    ReadError::TrailingBytes
130}
131
132impl From<PreallocationError> for ReadError {
133    fn from(PreallocationError { needed, limit }: PreallocationError) -> ReadError {
134        ReadError::PreallocationSizeLimit { needed, limit }
135    }
136}
137
138impl From<PreallocationError> for WriteError {
139    fn from(PreallocationError { needed, limit }: PreallocationError) -> WriteError {
140        WriteError::PreallocationSizeLimit { needed, limit }
141    }
142}
143
144#[cold]
145pub const fn tag_encoding_overflow(encoding: &'static str) -> TagEncodingOverflow {
146    TagEncodingOverflow(encoding)
147}
148
149impl From<TagEncodingOverflow> for ReadError {
150    fn from(err: TagEncodingOverflow) -> Self {
151        ReadError::TagEncodingOverflow(err.0)
152    }
153}
154
155impl From<TagEncodingOverflow> for WriteError {
156    fn from(err: TagEncodingOverflow) -> Self {
157        WriteError::TagEncodingOverflow(err.0)
158    }
159}