1use std::io;
5use thiserror::Error as ThisError;
6
7pub type Result<T> = std::result::Result<T, Error>;
9
10#[derive(ThisError, Debug)]
13#[non_exhaustive]
14pub enum ParseError {
15 #[error("value {value} is outside {bound}")]
16 OutOfBounds { value: String, bound: String },
17
18 #[error("unknown format: {0}")]
19 UnknownFormat(String),
20
21 #[error("unknown filetype: {0}")]
22 UnknownFileType(String),
23
24 #[error("expected a {expected} file, got {got}")]
28 WrongFormat { expected: &'static str, got: String },
29
30 #[error("{0}")]
31 AssertFail(String),
32
33 #[error(
39 "{format}: schema version {version} is not supported (known: {supported:?}); \
40 refusing to decode rather than risk misreading fields"
41 )]
42 UnsupportedVersion {
43 format: &'static str,
44 version: u32,
45 supported: &'static [u32],
46 },
47
48 #[error(
51 "{format}: the body is {got} bytes where the format holds {expected}; \
52 refusing rather than misread fields"
53 )]
54 WrongBodyLength {
55 format: String,
56 got: u64,
57 expected: u64,
58 },
59}
60
61impl From<std::convert::Infallible> for ParseError {
63 fn from(never: std::convert::Infallible) -> Self {
64 match never {}
65 }
66}
67
68#[derive(ThisError, Debug)]
71#[non_exhaustive]
72pub enum Error {
73 #[error(transparent)]
74 Io(#[from] io::Error),
75
76 #[error(transparent)]
77 Parse(#[from] ParseError),
78
79 #[cfg(feature = "bundle")]
80 #[error(transparent)]
81 Zip(#[from] zip::result::ZipError),
82}
83
84pub(crate) fn try_vec(len: usize) -> std::result::Result<Vec<u8>, ParseError> {
87 let mut buf = Vec::new();
88 buf.try_reserve_exact(len)
89 .map_err(|_| ParseError::OutOfBounds {
90 value: format!("{len} bytes"),
91 bound: "an allocation that fits memory".into(),
92 })?;
93 buf.resize(len, 0);
94 Ok(buf)
95}