1#[derive(Debug)]
2pub enum Key {
3 Str(String),
4 Uint(u64),
5 Nint(u64),
6}
7
8impl std::fmt::Display for Key {
9 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10 match self {
11 Key::Str(x) => write!(f, "\"{}\"", x),
12 Key::Uint(x) => write!(f, "{}", x),
13 Key::Nint(x) => write!(f, "-{}", x),
14 }
15 }
16}
17
18#[derive(Debug)]
19pub enum DeserializeFailure {
20 BreakInDefiniteLen,
21 CBOR(cbor_event::Error),
22 DefiniteLenMismatch(u64, Option<u64>),
23 DuplicateKey(Key),
24 EndingBreakMissing,
25 ExpectedNull,
26 FixedValueMismatch{
27 found: Key,
28 expected: Key,
29 },
30 MandatoryFieldMissing(Key),
31 NoVariantMatched,
32 TagMismatch{
33 found: u64,
34 expected: u64,
35 },
36 UnknownKey(Key),
37 UnexpectedKeyType(cbor_event::Type),
38}
39
40#[derive(Debug)]
42pub struct DeserializeError {
43 pub location: Option<String>,
44 pub failure: DeserializeFailure,
45}
46
47impl DeserializeError {
48 pub fn new<T: Into<String>>(location: T, failure: DeserializeFailure) -> Self {
49 Self {
50 location: Some(location.into()),
51 failure,
52 }
53 }
54
55 pub fn annotate<T: Into<String>>(self, location: T) -> Self {
56 match self.location {
57 Some(loc) => Self::new(format!("{}.{}", location.into(), loc), self.failure),
58 None => Self::new(location, self.failure),
59 }
60 }
61}
62
63impl std::fmt::Display for DeserializeError {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 match &self.location {
66 Some(loc) => write!(f, "Deserialization failed in {} because: ", loc),
67 None => write!(f, "Deserialization: "),
68 }?;
69 match &self.failure {
70 DeserializeFailure::BreakInDefiniteLen => write!(f, "Encountered CBOR Break while reading definite length sequence"),
71 DeserializeFailure::CBOR(e) => e.fmt(f),
72 DeserializeFailure::DefiniteLenMismatch(found, expected) => {
73 write!(f, "Definite length mismatch: found {}", found)?;
74 if let Some(expected_elems) = expected {
75 write!(f, ", expected: {}", expected_elems)?;
76 }
77 Ok(())
78 },
79 DeserializeFailure::DuplicateKey(key) => write!(f, "Duplicate key: {}", key),
80 DeserializeFailure::EndingBreakMissing => write!(f, "Missing ending CBOR Break"),
81 DeserializeFailure::ExpectedNull => write!(f, "Expected null, found other type"),
82 DeserializeFailure::FixedValueMismatch{ found, expected } => write!(f, "Expected fixed value {} found {}", expected, found),
83 DeserializeFailure::MandatoryFieldMissing(key) => write!(f, "Mandatory field {} not found", key),
84 DeserializeFailure::NoVariantMatched => write!(f, "No variant matched"),
85 DeserializeFailure::TagMismatch{ found, expected } => write!(f, "Expected tag {}, found {}", expected, found),
86 DeserializeFailure::UnknownKey(key) => write!(f, "Found unexpected key {}", key),
87 DeserializeFailure::UnexpectedKeyType(ty) => write!(f, "Found unexpected key of CBOR type {:?}", ty),
88 }
89 }
90}
91
92impl From<DeserializeError> for JsError {
93 fn from(e: DeserializeError) -> JsError {
94 JsError::from_str(&e.to_string())
95 }
96}
97
98impl From<DeserializeFailure> for DeserializeError {
99 fn from(failure: DeserializeFailure) -> DeserializeError {
100 DeserializeError {
101 location: None,
102 failure,
103 }
104 }
105}
106
107impl From<cbor_event::Error> for DeserializeError {
108 fn from(err: cbor_event::Error) -> DeserializeError {
109 DeserializeError {
110 location: None,
111 failure: DeserializeFailure::CBOR(err),
112 }
113 }
114}
115
116#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
120pub type JsError = wasm_bindgen::JsValue;
121
122#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
123#[derive(Debug, Clone)]
124pub struct JsError {
125 msg: String,
126}
127
128#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
129impl JsError {
130 pub fn from_str(s: &str) -> Self {
131 Self {
132 msg: s.to_owned(),
133 }
134 }
135
136 pub fn as_string(&self) -> Option<String> {
138 Some(self.msg.clone())
139 }
140}
141
142#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
143impl std::fmt::Display for JsError {
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 write!(f, "{}", self.msg)
146 }
147}