scale_encode/error/
mod.rs1mod context;
18
19use alloc::{borrow::Cow, boxed::Box, string::String};
20use core::fmt::Display;
21
22pub use context::{Context, Location};
23
24#[derive(Debug)]
26pub struct Error {
27 context: Context,
28 kind: ErrorKind,
29}
30
31impl core::error::Error for Error {}
32
33impl Error {
34 pub fn new(kind: ErrorKind) -> Error {
36 Error {
37 context: Context::new(),
38 kind,
39 }
40 }
41 pub fn custom(error: impl core::error::Error + Send + Sync + 'static) -> Error {
43 Error::new(ErrorKind::Custom(Box::new(error)))
44 }
45 pub fn custom_str(error: &'static str) -> Error {
47 #[derive(Debug, thiserror::Error)]
48 #[error("{0}")]
49 pub struct StrError(pub &'static str);
50
51 Error::new(ErrorKind::Custom(Box::new(StrError(error))))
52 }
53 pub fn custom_string(error: String) -> Error {
55 #[derive(Debug, thiserror::Error)]
56 #[error("{0}")]
57 pub struct StringError(String);
58
59 Error::new(ErrorKind::Custom(Box::new(StringError(error))))
60 }
61 pub fn kind(&self) -> &ErrorKind {
63 &self.kind
64 }
65 pub fn context(&self) -> &Context {
67 &self.context
68 }
69 pub fn at(mut self, loc: Location) -> Self {
71 self.context.push(loc);
72 Error {
73 context: self.context,
74 kind: self.kind,
75 }
76 }
77 pub fn at_idx(mut self, idx: usize) -> Self {
79 self.context.push(Location::idx(idx));
80 Error {
81 context: self.context,
82 kind: self.kind,
83 }
84 }
85 pub fn at_field(mut self, field: impl Into<Cow<'static, str>>) -> Self {
87 self.context.push(Location::field(field));
88 Error {
89 context: self.context,
90 kind: self.kind,
91 }
92 }
93 pub fn at_variant(mut self, variant: impl Into<Cow<'static, str>>) -> Self {
95 self.context.push(Location::variant(variant));
96 Error {
97 context: self.context,
98 kind: self.kind,
99 }
100 }
101}
102
103impl Display for Error {
104 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
105 let path = self.context.path();
106 let kind = &self.kind;
107 write!(f, "Error at {path}: {kind}")
108 }
109}
110
111#[derive(Debug, thiserror::Error)]
113pub enum ErrorKind {
114 #[error("Failed to resolve type: {0}")]
116 TypeResolvingError(String),
117 #[error("Cannot find type with identifier {0}")]
119 TypeNotFound(String),
120 #[error("Cannot encode {actual:?} into type with ID {expected_id}")]
122 WrongShape {
123 actual: Kind,
125 expected_id: String,
127 },
128 #[error("Cannot encode to type; expected length {expected_len} but got length {actual_len}")]
130 WrongLength {
131 actual_len: usize,
133 expected_len: usize,
135 },
136 #[error("Number {value} is out of range for target type with identifier {expected_id}")]
138 NumberOutOfRange {
139 value: String,
141 expected_id: String,
143 },
144 #[error("Variant {name} does not exist on type with identifier {expected_id}")]
146 CannotFindVariant {
147 name: String,
149 expected_id: String,
151 },
152 #[error("Field {name} does not exist in our source struct")]
154 CannotFindField {
155 name: String,
157 },
158 #[error("Custom error: {0}")]
160 Custom(Box<dyn core::error::Error + Send + Sync + 'static>),
161}
162
163#[allow(missing_docs)]
165#[derive(Copy, Clone, PartialEq, Eq, Debug)]
166pub enum Kind {
167 Struct,
168 Tuple,
169 Variant,
170 Array,
171 BitSequence,
172 Bool,
173 Char,
174 Str,
175 Number,
176}