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
//! Error types for SCLS parsing and validation.
use crate::hash::Digest;
use thiserror::Error;
/// Errors that can occur when reading or writing SCLS files.
#[derive(Error, Debug)]
pub enum SclsError {
/* Parsing errors ****************************************************************************/
/// Invalid magic bytes in header
#[error("invalid magic bytes: expected 'SCLS', found {found:?}")]
InvalidMagic { found: Vec<u8> },
/// Unsupported file format version
#[error("unsupported version: {0}")]
UnsupportedVersion(u32),
/// I/O error during reading or writing
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
/// Malformed record structure
#[error("malformed record: {0}")]
MalformedRecord(String),
/// Truncated record length prefix
#[error("truncated record length prefix")]
TruncatedRecord,
/// Unknown record type encountered
#[error("unknown record type: 0x{0:02x}")]
UnknownRecordType(u8),
/* Record sequence verification errors *******************************************************/
/// Unexpected record type found in stream
#[error("unexpected record type: found {found}, expected {expected}")]
UnexpectedRecord { found: String, expected: String },
/// Unexpected EOF found in stream
#[error("unexpected EOF: expected {expected}")]
UnexpectedEof { expected: String },
/* Structural verification errors ************************************************************/
/// Record sequence number not increasing within namespace
#[error(
"record sequence is not increasing within namespace {namespace}: previous {previous}, found {found}"
)]
SeqnoDisordered {
namespace: String,
previous: u64,
found: u64,
},
/// Chunk namespaces not in bytewise ascending order
#[error(
"chunk namespaces are not in bytewise order: previous \"{previous}\", found \"{found}\""
)]
NamespaceDisordered { previous: String, found: String },
/// Entry keys not in lexicographically ascending order
///
/// Note: This check is not performed by default to avoid materialisation; see
/// [`CheckStructure`](crate::reader::CheckStructure) and
/// [`VerifyOptions::default`](crate::reader::VerifyOptions::default).
#[error(
"chunk {seqno} does not have entry keys in lexicographically ascending order over namespace {namespace}"
)]
KeysDisordered { namespace: String, seqno: u64 },
/// Manifest namespace set differs from chunk namespaces
#[error("mismatching namespace sets: in chunks {in_chunks:?}, in manifest {in_manifest:?}")]
NamespaceMismatch {
in_chunks: Vec<String>,
in_manifest: Vec<String>,
},
/// Manifest namespace chunk counts differ
#[error("mismatching chunk counts for {namespace}: expected {expected}, found {found}")]
NamespaceChunkMismatch {
namespace: String,
expected: u64,
found: u64,
},
/// Manifest namespace entry counts differ
#[error("mismatching entry counts for {namespace}: expected {expected}, found {found}")]
NamespaceEntryMismatch {
namespace: String,
expected: u64,
found: u64,
},
/* Integrity verification errors *************************************************************/
/// Chunk digest mismatch
#[error("mismatching digest in chunk {seqno}: expected {expected}, computed {computed}")]
ChunkDigestMismatch {
seqno: u64,
expected: Digest,
computed: Digest,
},
/// Namespace root digest mismatch
#[error(
"mismatching namespace root digest for {namespace}: expected {expected}, computed {computed}"
)]
NamespaceDigestMismatch {
namespace: String,
expected: Digest,
computed: Digest,
},
/// Global root digest mismatch
#[error("mismatching global root digest: expected {expected}, computed {computed}")]
GlobalDigestMismatch { expected: Digest, computed: Digest },
/* Writer errors *****************************************************************************/
/// Writer builder missing required output parameter
#[error("writer builder is missing its required output parameter")]
WriterBuilderMissingOutput,
/// Writer builder missing required slot number parameter
#[error("writer builder is missing its required slot number parameter")]
WriterBuilderMissingSlotNo,
/// Overflow error when writing to the wire format
#[error("{0} length overflow in wire format")]
WireLengthOverflow(String),
/// Inconsistent entry key lengths within a namespace
#[error("inconsistent entry key length in {namespace}: expected {expected}, found {found}")]
InconsistentKeyLength {
namespace: String,
expected: usize,
found: usize,
},
/// Attempted to write non-monotonic namespace
///
/// Note, this is effectively equivalent to [`SclsError::NamespaceDisordered`]. We maintain the
/// distinction because they occur under semantically distinct operations.
#[error("Namespaces are not in bytewise order: previous \"{previous}\", found \"{found}\"")]
NonMonotonicNamespace { previous: String, found: String },
/// Attempted to write non-strictly monotonic entry key
///
/// Note, this is similar to [`SclsError::KeysDisordered`]. We maintain the distinction because
/// they occur under semantically distinct operations.
#[error("Entry keys are not strictly lexicographically increasing in {namespace}")]
NonStrictlyMonotonicKeys { namespace: String },
/// Manifest offset does not match the on-wire record length
#[error("Manifest offset should match the record length: expected {expected}, found {found}")]
InconsistentManifestOffset { expected: u32, found: u32 },
}
/// Convenience type alias for Results with SclsError.
pub type Result<T> = std::result::Result<T, SclsError>;