1use alloc::borrow::Cow;
4use alloc::boxed::Box;
5use alloc::vec::Vec;
6
7use core::fmt;
8
9#[derive(Clone, PartialEq, Eq)]
15pub struct DecodeError {
16 inner: Box<Inner>,
17}
18
19#[derive(Clone, PartialEq, Eq)]
20struct Inner {
21 description: Cow<'static, str>,
23 stack: Vec<(&'static str, &'static str)>,
27}
28
29impl DecodeError {
30 #[doc(hidden)]
34 #[cold]
35 pub fn new(description: impl Into<Cow<'static, str>>) -> DecodeError {
36 DecodeError {
37 inner: Box::new(Inner {
38 description: description.into(),
39 stack: Vec::new(),
40 }),
41 }
42 }
43
44 #[doc(hidden)]
48 pub fn push(&mut self, message: &'static str, field: &'static str) {
49 self.inner.stack.push((message, field));
50 }
51}
52
53impl fmt::Debug for DecodeError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 f.debug_struct("DecodeError")
56 .field("description", &self.inner.description)
57 .field("stack", &self.inner.stack)
58 .finish()
59 }
60}
61
62impl fmt::Display for DecodeError {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 f.write_str("failed to decode Protobuf message: ")?;
65 for &(message, field) in &self.inner.stack {
66 write!(f, "{}.{}: ", message, field)?;
67 }
68 f.write_str(&self.inner.description)
69 }
70}
71
72#[cfg(feature = "std")]
73impl std::error::Error for DecodeError {}
74
75#[cfg(feature = "std")]
76impl From<DecodeError> for std::io::Error {
77 fn from(error: DecodeError) -> std::io::Error {
78 std::io::Error::new(std::io::ErrorKind::InvalidData, error)
79 }
80}
81
82#[derive(Copy, Clone, Debug, PartialEq, Eq)]
88pub struct EncodeError {
89 required: usize,
90 remaining: usize,
91}
92
93impl EncodeError {
94 pub(crate) fn new(required: usize, remaining: usize) -> EncodeError {
96 EncodeError {
97 required,
98 remaining,
99 }
100 }
101
102 pub fn required_capacity(&self) -> usize {
104 self.required
105 }
106
107 pub fn remaining(&self) -> usize {
109 self.remaining
110 }
111}
112
113impl fmt::Display for EncodeError {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 write!(
116 f,
117 "failed to encode Protobuf message; insufficient buffer capacity (required: {}, remaining: {})",
118 self.required, self.remaining
119 )
120 }
121}
122
123#[cfg(feature = "std")]
124impl std::error::Error for EncodeError {}
125
126#[cfg(feature = "std")]
127impl From<EncodeError> for std::io::Error {
128 fn from(error: EncodeError) -> std::io::Error {
129 std::io::Error::new(std::io::ErrorKind::InvalidInput, error)
130 }
131}