1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//! Library error types.
//!
use fog_crypto::{hash::Hash, CryptoError};
use std::fmt;
use serde::{de, ser};
/// A fog-pack Result, normally returning a fog-pack [`Error`].
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[allow(unused)]
#[derive(Clone, Debug)]
enum ValidateError {
/// Validation failed inside an array
InArray {
index: usize,
err: Box<ValidateError>,
},
/// Validation failed inside a map
InMap {
key: String,
err: Box<ValidateError>,
},
/// Validation failed inside an enum
InEnum {
name: String,
err: Box<ValidateError>,
},
/// Validation of an array failed at a specific index
FailArray { index: usize, err: String },
/// Validation of a map failed at a specific key
FailMap { key: String, err: String },
/// All of the available "multi" validators failed
FailMulti { errs: Vec<ValidateError> },
/// The core validation error
FailValue {
failure: String,
value: crate::value::Value,
},
/// Some other fog-pack error occurred in here
SubError(Box<Error>),
}
/// A fog-pack error. Encompasses any issues that can happen during validation,
/// encoding, or decoding.
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Error {
/// Occurs when a subtype is using a version format that is no longer accepted. This is mainly
/// for recognizing when the Cryptographic types and signatures use old, no longer accepted
/// algorithms.
OldVersion(String),
/// Occurs when a schema doesn't match the document's schema, a Schema was used when one isn't
/// specified by the document, or a NoSchema was used when a document specified a schema.
SchemaMismatch {
/// The actual schema of the document
actual: Option<Hash>,
/// The expected schema of the document
expected: Option<Hash>,
},
/// Occurs when serde serialization or deserialization fails
SerdeFail(String),
/// Occurs when the header (compression marker and optional schema) failed to parse correctly.
BadHeader(String),
/// Occurs when zstd compression fails, possibly due to a dictionary not being present in a
/// schema, a checksum failing, or any of the other zstd failure modes.
FailDecompress(String),
/// Document/Entry/Query was greater than maximum allowed size on decode
LengthTooLong {
/// The maximum allowed size
max: usize,
/// The object's actual size
actual: usize,
},
/// Document/Entry/Query ended too early.
LengthTooShort {
/// What step of the decoding we were on when it failed.
step: &'static str,
/// The actual length of the object
actual: usize,
/// The remaining length of the object that we were expecting
expected: usize,
},
/// Signature attached to end of Document/Entry/Query didn't validate
BadSignature,
/// Basic fog-pack encoding failure
BadEncode(String),
/// Schema validation failure.
FailValidate(String),
/// Failure within the cryptographic submodule.
CryptoError(CryptoError),
/// Schema or validation hit some parsing limit.
ParseLimit(String),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::OldVersion(ref err) => write!(f, "Old version: {}", err),
Error::SchemaMismatch {
ref actual,
ref expected,
} => match (actual, expected) {
(Some(actual), Some(expected)) => write!(
f,
"Expected schema {}, but document used schema {}",
expected, actual
),
(Some(actual), None) => {
write!(f, "Expected no schema, but document used schema {}", actual)
}
(None, Some(expected)) => write!(
f,
"Expected schema {}, but document used no schema",
expected
),
(None, None) => write!(
f,
"Expected and got no schema (this should not have been an error)"
),
},
Error::SerdeFail(ref msg) => f.write_str(msg),
Error::BadHeader(ref err) => write!(f, "Data has bad header format: {}", err),
Error::FailDecompress(ref err) => write!(f, "Failed decompression step: {}", err),
Error::LengthTooLong { max, actual } => write!(
f,
"Data too long: was {} bytes, maximum allowed is {}",
actual, max
),
Error::LengthTooShort {
step,
actual,
expected,
} => write!(
f,
"Expected data length {}, but got {} on step [{}]",
expected, actual, step
),
Error::BadSignature => write!(f, "A signature failed to verify"),
Error::BadEncode(ref err) => write!(f, "Basic data encoding failure: {}", err),
Error::FailValidate(ref err) => write!(f, "Failed validation: {}", err),
Error::CryptoError(_) => write!(f, "Cryptographic Error"),
Error::ParseLimit(ref err) => write!(f, "Hit parsing limit: {}", err),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
Error::CryptoError(ref err) => Some(err),
_ => None,
}
}
}
impl std::convert::From<CryptoError> for Error {
fn from(e: CryptoError) -> Self {
Self::CryptoError(e)
}
}
impl ser::Error for Error {
fn custom<T: fmt::Display>(msg: T) -> Self {
Error::SerdeFail(msg.to_string())
}
}
impl de::Error for Error {
fn custom<T: fmt::Display>(msg: T) -> Self {
Error::SerdeFail(msg.to_string())
}
}