ipld_nostd/dag/
error.rs

1//! When serializing or deserializing DAG-CBOR goes wrong.
2
3use {
4	alloc::{
5		collections::TryReserveError,
6		string::{String, ToString},
7	},
8	core::{convert::Infallible, fmt, num::TryFromIntError},
9	serde::{de, ser},
10};
11
12/// An encoding error.
13#[derive(Debug)]
14pub enum EncodeError<E> {
15	/// Custom error message.
16	Msg(String),
17	/// IO Error.
18	Write(E),
19}
20
21impl<E> From<E> for EncodeError<E> {
22	fn from(err: E) -> EncodeError<E> {
23		EncodeError::Write(err)
24	}
25}
26
27impl<E: fmt::Debug> ser::Error for EncodeError<E> {
28	fn custom<T: fmt::Display>(msg: T) -> Self {
29		EncodeError::Msg(msg.to_string())
30	}
31}
32
33impl<E: fmt::Debug> ser::StdError for EncodeError<E> {}
34
35impl<E: fmt::Debug> fmt::Display for EncodeError<E> {
36	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37		fmt::Debug::fmt(self, f)
38	}
39}
40
41impl<E: fmt::Debug> From<cbor4ii::EncodeError<E>> for EncodeError<E> {
42	fn from(err: cbor4ii::EncodeError<E>) -> EncodeError<E> {
43		match err {
44			cbor4ii::EncodeError::Write(e) => EncodeError::Write(e),
45			// Needed as `cbor4ii::EncodeError` is markes as non_exhaustive
46			_ => EncodeError::Msg(err.to_string()),
47		}
48	}
49}
50
51/// A decoding error.
52#[derive(Debug)]
53pub enum DecodeError<E> {
54	/// Custom error message.
55	Msg(String),
56	/// IO error.
57	Read(E),
58	/// End of file.
59	Eof,
60	/// Unexpected byte.
61	Mismatch {
62		/// Expected CBOR major type.
63		expect_major: u8,
64		/// Unexpected byte.
65		byte: u8,
66	},
67	/// Unexpected type.
68	TypeMismatch {
69		/// Type name.
70		name: &'static str,
71		/// Type byte.
72		byte: u8,
73	},
74	/// Too large integer.
75	CastOverflow(TryFromIntError),
76	/// Overflowing 128-bit integers.
77	Overflow {
78		/// Type of integer.
79		name: &'static str,
80	},
81	/// Decoding bytes/strings might require a borrow.
82	RequireBorrowed {
83		/// Type name (e.g. "bytes", "str").
84		name: &'static str,
85	},
86	/// Length wasn't large enough.
87	RequireLength {
88		/// Type name.
89		name: &'static str,
90		/// Required length.
91		expect: usize,
92		/// Given length.
93		value: usize,
94	},
95	/// Invalid UTF-8.
96	InvalidUtf8(core::str::Utf8Error),
97	/// Unsupported byte.
98	Unsupported {
99		/// Unsupported bute.
100		byte: u8,
101	},
102	/// Recursion limit reached.
103	DepthLimit,
104	/// Trailing data.
105	TrailingData,
106	/// Indefinite sized item was encountered.
107	IndefiniteSize,
108}
109
110impl<E> From<E> for DecodeError<E> {
111	fn from(err: E) -> DecodeError<E> {
112		DecodeError::Read(err)
113	}
114}
115
116impl<E: fmt::Debug> de::Error for DecodeError<E> {
117	fn custom<T: fmt::Display>(msg: T) -> Self {
118		DecodeError::Msg(msg.to_string())
119	}
120}
121
122impl<E: fmt::Debug> ser::StdError for DecodeError<E> {}
123
124impl<E: fmt::Debug> fmt::Display for DecodeError<E> {
125	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126		fmt::Debug::fmt(self, f)
127	}
128}
129
130impl<E: fmt::Debug> From<cbor4ii::DecodeError<E>> for DecodeError<E> {
131	fn from(err: cbor4ii::DecodeError<E>) -> DecodeError<E> {
132		match err {
133			cbor4ii::DecodeError::Read(read) => DecodeError::Read(read),
134			cbor4ii::DecodeError::Eof => DecodeError::Eof,
135			cbor4ii::DecodeError::Mismatch { expect_major, byte } => {
136				DecodeError::Mismatch { expect_major, byte }
137			}
138			cbor4ii::DecodeError::TypeMismatch { name, byte } => {
139				DecodeError::TypeMismatch { name, byte }
140			}
141			cbor4ii::DecodeError::CastOverflow(overflow) => {
142				DecodeError::CastOverflow(overflow)
143			}
144			cbor4ii::DecodeError::Overflow { name } => DecodeError::Overflow { name },
145			cbor4ii::DecodeError::RequireBorrowed { name } => {
146				DecodeError::RequireBorrowed { name }
147			}
148			cbor4ii::DecodeError::RequireLength {
149				name,
150				expect,
151				value,
152			} => DecodeError::RequireLength {
153				name,
154				expect,
155				value,
156			},
157			cbor4ii::DecodeError::InvalidUtf8(invalid) => {
158				DecodeError::InvalidUtf8(invalid)
159			}
160			cbor4ii::DecodeError::Unsupported { byte } => {
161				DecodeError::Unsupported { byte }
162			}
163			cbor4ii::DecodeError::DepthLimit => DecodeError::DepthLimit,
164			// Needed as `cbor4ii::EncodeError` is markes as non_exhaustive
165			_ => DecodeError::Msg(err.to_string()),
166		}
167	}
168}
169
170/// Encode and Decode error combined.
171#[derive(Debug, thiserror_core2::Error)]
172pub enum CodecError {
173	/// A decoding error.
174	#[error("Decoding error: {0}")]
175	Decode(DecodeError<Infallible>),
176	/// An encoding error.
177	#[error("Encoding error: {0}")]
178	Encode(EncodeError<TryReserveError>),
179	/// A decoding error.
180	#[error("Decoding IO error: {0}")]
181	DecodeIo(DecodeError<core2::io::Error>),
182	/// An encoding error.
183	#[error("Encoding IO error: {0}")]
184	EncodeIo(EncodeError<core2::io::Error>),
185}
186
187impl From<DecodeError<Infallible>> for CodecError {
188	fn from(error: DecodeError<Infallible>) -> Self {
189		Self::Decode(error)
190	}
191}
192
193impl From<EncodeError<TryReserveError>> for CodecError {
194	fn from(error: EncodeError<TryReserveError>) -> Self {
195		Self::Encode(error)
196	}
197}