1use thiserror::Error;
7
8#[derive(Debug, Error)]
10pub enum EncodeError {
11 #[error("error-atproto-dasl-encode-1 I/O error: {0}")]
13 Io(#[from] std::io::Error),
14
15 #[error("error-atproto-dasl-encode-2 Invalid float value: {reason}")]
17 InvalidFloat {
18 reason: String,
20 },
21
22 #[error("error-atproto-dasl-encode-3 Indefinite length encoding not supported")]
24 IndefiniteLengthNotSupported,
25
26 #[error("error-atproto-dasl-encode-4 Map key missing before value")]
28 MapKeyMissing,
29
30 #[error("error-atproto-dasl-encode-5 Serialization error: {0}")]
32 Serialization(String),
33
34 #[error("error-atproto-dasl-encode-6 Integer overflow: value too large")]
36 IntegerOverflow,
37
38 #[error("error-atproto-dasl-encode-7 Depth limit exceeded: max {max}")]
40 DepthLimitExceeded {
41 max: usize,
43 },
44
45 #[error("error-atproto-dasl-encode-8 Output too large: max {max} bytes")]
47 OutputTooLarge {
48 max: usize,
50 },
51}
52
53impl serde::ser::Error for EncodeError {
54 fn custom<T: std::fmt::Display>(msg: T) -> Self {
55 EncodeError::Serialization(msg.to_string())
56 }
57}
58
59#[derive(Debug, Error)]
61pub enum DecodeError {
62 #[error("error-atproto-dasl-decode-1 I/O error: {0}")]
64 Io(#[from] std::io::Error),
65
66 #[error("error-atproto-dasl-decode-2 Unexpected end of input")]
68 UnexpectedEof,
69
70 #[error("error-atproto-dasl-decode-3 Invalid CBOR structure: {reason}")]
72 InvalidCbor {
73 reason: String,
75 },
76
77 #[error(
79 "error-atproto-dasl-decode-4 Non-canonical encoding: type {major_type}, info {additional_info}, value {value}"
80 )]
81 NonCanonicalEncoding {
82 major_type: u8,
84 additional_info: u8,
86 value: u64,
88 },
89
90 #[error("error-atproto-dasl-decode-5 Unsupported CBOR tag: {tag}")]
92 UnsupportedTag {
93 tag: u64,
95 },
96
97 #[error("error-atproto-dasl-decode-6 Map key must be a string")]
99 MapKeyNotString,
100
101 #[error("error-atproto-dasl-decode-7 Invalid CID: {reason}")]
103 InvalidCid {
104 reason: String,
106 },
107
108 #[error("error-atproto-dasl-decode-8 CID tag must be followed by byte string")]
110 InvalidCidContent,
111
112 #[error("error-atproto-dasl-decode-9 Invalid float value: NaN and Infinity not allowed")]
114 InvalidFloat,
115
116 #[error("error-atproto-dasl-decode-10 Unsupported simple value: {value}")]
118 UnsupportedSimpleValue {
119 value: u8,
121 },
122
123 #[error("error-atproto-dasl-decode-11 Indefinite length encoding not supported")]
125 IndefiniteLengthNotSupported,
126
127 #[error("error-atproto-dasl-decode-12 Type mismatch: expected {expected}, found {found}")]
129 TypeMismatch {
130 expected: &'static str,
132 found: String,
134 },
135
136 #[error("error-atproto-dasl-decode-13 Maximum nesting depth exceeded: {depth} > {max}")]
138 MaxDepthExceeded {
139 depth: usize,
141 max: usize,
143 },
144
145 #[error("error-atproto-dasl-decode-14 Allocation limit exceeded: {size} > {max}")]
147 AllocationExceeded {
148 size: usize,
150 max: usize,
152 },
153
154 #[error("error-atproto-dasl-decode-15 Invalid UTF-8: {0}")]
156 InvalidUtf8(#[from] std::string::FromUtf8Error),
157
158 #[error("error-atproto-dasl-decode-16 Map keys not in canonical order")]
160 MapKeysNotSorted,
161
162 #[error("error-atproto-dasl-decode-17 Reserved additional info value: {value}")]
164 ReservedAdditionalInfo {
165 value: u8,
167 },
168
169 #[error("error-atproto-dasl-decode-18 Deserialization error: {0}")]
171 Deserialization(String),
172
173 #[error("error-atproto-dasl-decode-19 Trailing data after top-level object")]
175 TrailingData,
176
177 #[error("error-atproto-dasl-decode-20 Non-canonical float encoding: expected 64-bit double")]
179 NonCanonicalFloat,
180
181 #[error("error-atproto-dasl-decode-21 Duplicate map key")]
183 DuplicateMapKey,
184
185 #[error("error-atproto-dasl-decode-22 Float values not allowed")]
187 FloatsNotAllowed,
188
189 #[error("error-atproto-dasl-decode-23 Integer {value} outside i64 range")]
191 IntegerOutOfRange {
192 value: String,
194 },
195
196 #[error("error-atproto-dasl-decode-24 Array too large: {count} elements (max {max})")]
198 ArrayTooLarge {
199 count: usize,
201 max: usize,
203 },
204
205 #[error("error-atproto-dasl-decode-25 Map too large: {count} entries (max {max})")]
207 MapTooLarge {
208 count: usize,
210 max: usize,
212 },
213}
214
215impl serde::de::Error for DecodeError {
216 fn custom<T: std::fmt::Display>(msg: T) -> Self {
217 DecodeError::Deserialization(msg.to_string())
218 }
219}
220
221#[derive(Debug, Error)]
223pub enum VarintError {
224 #[error("error-atproto-dasl-varint-1 Varint overflow: exceeded maximum size")]
226 Overflow,
227
228 #[error("error-atproto-dasl-varint-2 Unexpected end of input")]
230 UnexpectedEof,
231
232 #[error("error-atproto-dasl-varint-3 Non-minimal encoding detected")]
234 NonMinimal,
235}
236
237#[derive(Debug, Error)]
239pub enum CarError {
240 #[error("error-atproto-dasl-car-1 Invalid CAR header: {reason}")]
242 InvalidHeader {
243 reason: String,
245 },
246
247 #[error("error-atproto-dasl-car-2 Unsupported CAR version: {version}")]
249 UnsupportedVersion {
250 version: u64,
252 },
253
254 #[error("error-atproto-dasl-car-3 CID mismatch: expected {expected}, got {actual}")]
256 CidMismatch {
257 expected: String,
259 actual: String,
261 },
262
263 #[error("error-atproto-dasl-car-4 Invalid block data: {reason}")]
265 InvalidBlock {
266 reason: String,
268 },
269
270 #[error("error-atproto-dasl-car-5 DAG-CBOR encode error: {0}")]
272 DagCborEncode(#[from] EncodeError),
273
274 #[error("error-atproto-dasl-car-6 DAG-CBOR decode error: {0}")]
276 DagCborDecode(DecodeError),
277
278 #[error("error-atproto-dasl-car-7 I/O error: {0}")]
280 Io(#[from] std::io::Error),
281
282 #[error("error-atproto-dasl-car-8 Varint error: {0}")]
284 Varint(#[from] VarintError),
285
286 #[error("error-atproto-dasl-car-9 Invalid CID: {reason}")]
288 InvalidCid {
289 reason: String,
291 },
292
293 #[error("error-atproto-dasl-car-10 CAR file must have at least one root CID")]
295 NoRoots,
296
297 #[error("error-atproto-dasl-car-11 CAR file too large: {size} bytes (max {max})")]
299 FileTooLarge {
300 size: u64,
302 max: u64,
304 },
305
306 #[error("error-atproto-dasl-car-12 Storage error: {0}")]
308 Storage(#[from] StorageError),
309}
310
311impl From<DecodeError> for CarError {
312 fn from(err: DecodeError) -> Self {
313 CarError::DagCborDecode(err)
314 }
315}
316
317#[derive(Debug, Error)]
319pub enum StorageError {
320 #[error("error-atproto-dasl-storage-1 Block not found: {cid}")]
322 BlockNotFound {
323 cid: String,
325 },
326
327 #[error("error-atproto-dasl-storage-2 Storage limit exceeded: {limit} bytes")]
329 CapacityExceeded {
330 limit: usize,
332 },
333
334 #[error("error-atproto-dasl-storage-3 Storage I/O error: {0}")]
336 Io(#[from] std::io::Error),
337
338 #[error("error-atproto-dasl-storage-4 Block too large: {size} bytes (max {max})")]
340 BlockTooLarge {
341 size: usize,
343 max: usize,
345 },
346
347 #[error("error-atproto-dasl-storage-5 Block count exceeded: {count} (max {max})")]
349 BlockCountExceeded {
350 count: usize,
352 max: usize,
354 },
355
356 #[error("error-atproto-dasl-storage-6 Depth exceeded: {depth} (max {max})")]
358 DepthExceeded {
359 depth: usize,
361 max: usize,
363 },
364}
365
366#[derive(Debug, Error)]
368pub enum DaslCidError {
369 #[error("error-atproto-dasl-cid-1 DASL requires CIDv1, got CIDv0")]
371 NotCidV1,
372
373 #[error(
375 "error-atproto-dasl-cid-2 Codec 0x{codec:x} not allowed in DASL (must be raw 0x55 or dag-cbor 0x71)"
376 )]
377 InvalidCodec {
378 codec: u64,
380 },
381
382 #[error(
384 "error-atproto-dasl-cid-3 Hash 0x{hash:x} not allowed in DASL (must be SHA-256 0x12 or BLAKE3 0x1e)"
385 )]
386 InvalidHash {
387 hash: u64,
389 },
390
391 #[error("error-atproto-dasl-cid-4 Digest length {len} != 32")]
393 InvalidDigestLength {
394 len: usize,
396 },
397
398 #[error("error-atproto-dasl-cid-5 Invalid CID: {reason}")]
400 InvalidCid {
401 reason: String,
403 },
404}
405
406#[derive(Debug, Error)]
408pub enum MaslError {
409 #[error("error-atproto-dasl-masl-1 Missing required field: {field}")]
411 MissingField {
412 field: String,
414 },
415
416 #[error("error-atproto-dasl-masl-2 Invalid path: {reason}")]
418 InvalidPath {
419 reason: String,
421 },
422
423 #[error("error-atproto-dasl-masl-3 Invalid resource: {reason}")]
425 InvalidResource {
426 reason: String,
428 },
429
430 #[error("error-atproto-dasl-masl-4 Document mode conflict: {reason}")]
432 ModeConflict {
433 reason: String,
435 },
436
437 #[error("error-atproto-dasl-masl-5 Invalid CAR format: {reason}")]
439 InvalidCarFormat {
440 reason: String,
442 },
443
444 #[error("error-atproto-dasl-masl-6 DAG-CBOR error: {0}")]
446 DagCbor(String),
447
448 #[error("error-atproto-dasl-masl-7 Invalid type: {reason}")]
450 InvalidType {
451 reason: String,
453 },
454
455 #[error(
457 "error-atproto-dasl-masl-8 Invalid reference: field '{field}' references non-existent path '{path}'"
458 )]
459 InvalidReference {
460 path: String,
462 field: String,
464 },
465}
466
467#[derive(Debug, Error)]
469pub enum RaslError {
470 #[error("error-atproto-dasl-rasl-1 Invalid scheme: expected 'rasl', got '{scheme}'")]
472 InvalidScheme {
473 scheme: String,
475 },
476
477 #[error("error-atproto-dasl-rasl-2 Missing CID in RASL URL")]
479 MissingCid,
480
481 #[error("error-atproto-dasl-rasl-3 Invalid CID: {reason}")]
483 InvalidCid {
484 reason: String,
486 },
487
488 #[error("error-atproto-dasl-rasl-4 Invalid hint: {reason}")]
490 InvalidHint {
491 reason: String,
493 },
494
495 #[error("error-atproto-dasl-rasl-5 URL parse error: {0}")]
497 UrlParse(#[from] url::ParseError),
498
499 #[error("error-atproto-dasl-rasl-6 Credentials not allowed in RASL URLs")]
501 CredentialsNotAllowed,
502
503 #[error("error-atproto-dasl-rasl-7 Fragments not allowed in RASL URLs")]
505 FragmentNotAllowed,
506
507 #[error("error-atproto-dasl-rasl-8 All retrieval hints failed")]
509 AllHintsFailed,
510
511 #[error("error-atproto-dasl-rasl-9 CID verification failed: {reason}")]
513 CidVerification {
514 reason: String,
516 },
517
518 #[cfg(feature = "reqwest")]
520 #[error("error-atproto-dasl-rasl-10 HTTP request failed for {url}: {reason}")]
521 HttpRequest {
522 url: String,
524 reason: String,
526 },
527
528 #[error("error-atproto-dasl-rasl-11 I/O error: {0}")]
530 Io(#[from] std::io::Error),
531
532 #[error("error-atproto-dasl-rasl-12 No hints provided for fetch")]
534 NoHints,
535
536 #[error("error-atproto-dasl-rasl-13 Directory handler error: {reason}")]
538 DirectoryError {
539 reason: String,
541 },
542}
543
544#[derive(Debug, Error)]
546pub enum TilesError {
547 #[error("error-atproto-dasl-tiles-1 MASL validation failed: {reason}")]
549 MaslValidation {
550 reason: String,
552 },
553
554 #[error("error-atproto-dasl-tiles-2 Tile manifest must be in bundle mode")]
556 NotBundleMode,
557
558 #[error("error-atproto-dasl-tiles-3 Tile manifest must have a name")]
560 MissingName,
561
562 #[error("error-atproto-dasl-tiles-4 Tile name too long: {chars} chars (max {max})")]
564 NameTooLong {
565 chars: usize,
567 max: usize,
569 },
570
571 #[error("error-atproto-dasl-tiles-5 Tile manifest must have a '/' root resource")]
573 MissingRootResource,
574}