Skip to main content

irontide_bencode/
error.rs

1use std::fmt;
2
3/// Result type alias for bencode operations.
4pub type Result<T> = std::result::Result<T, Error>;
5
6/// Errors that can occur during bencode serialization or deserialization.
7#[derive(Debug, thiserror::Error)]
8pub enum Error {
9    /// Integer overflow or invalid integer value.
10    #[error("invalid integer at position {position}: {detail}")]
11    InvalidInteger {
12        /// Byte offset where the error occurred.
13        position: usize,
14        /// Description of the problem.
15        detail: String,
16    },
17
18    /// Invalid byte string (bad length prefix, truncated, etc).
19    #[error("invalid byte string at position {position}: {detail}")]
20    InvalidByteString {
21        /// Byte offset where the error occurred.
22        position: usize,
23        /// Description of the problem.
24        detail: String,
25    },
26
27    /// Unexpected byte encountered during parsing.
28    #[error("unexpected byte {byte:#04x} at position {position}, expected {expected}")]
29    UnexpectedByte {
30        /// The byte that was found.
31        byte: u8,
32        /// Byte offset where the error occurred.
33        position: usize,
34        /// What was expected instead.
35        expected: &'static str,
36    },
37
38    /// Input ended prematurely.
39    #[error("unexpected end of input at position {position}: {context}")]
40    UnexpectedEof {
41        /// Byte offset where the error occurred.
42        position: usize,
43        /// Description of what was being parsed.
44        context: String,
45    },
46
47    /// Dictionary keys are not in sorted order (BEP 3 violation).
48    #[error("dictionary keys not sorted at position {position}")]
49    UnsortedKeys {
50        /// Byte offset of the out-of-order key.
51        position: usize,
52    },
53
54    /// Trailing bytes after the top-level value.
55    #[error("{count} trailing byte(s) after value at position {position}")]
56    TrailingData {
57        /// Byte offset where trailing data begins.
58        position: usize,
59        /// Number of trailing bytes.
60        count: usize,
61    },
62
63    /// The key in `find_dict_key_span` was not found.
64    #[error("key {key:?} not found in dictionary")]
65    KeyNotFound {
66        /// The key that was not found.
67        key: String,
68    },
69
70    /// Input is not a dictionary (for `find_dict_key_span`).
71    #[error("expected dictionary at position {position}")]
72    NotADictionary {
73        /// Byte offset where the non-dictionary value was found.
74        position: usize,
75    },
76
77    /// Custom error from serde.
78    #[error("{0}")]
79    Custom(String),
80}
81
82impl serde::ser::Error for Error {
83    fn custom<T: fmt::Display>(msg: T) -> Self {
84        Self::Custom(msg.to_string())
85    }
86}
87
88impl serde::de::Error for Error {
89    fn custom<T: fmt::Display>(msg: T) -> Self {
90        Self::Custom(msg.to_string())
91    }
92}