use core::fmt;
pub type Result<T> = core::result::Result<T, Error>;
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
#[cfg(feature = "std")]
Io(std::io::Error),
BadMagic,
UnsupportedVersion(u16),
Corrupt(&'static str),
ValueTooLarge,
}
#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
#[inline]
fn from(err: std::io::Error) -> Self {
Error::Io(err)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
#[cfg(feature = "std")]
Error::Io(err) => write!(f, "i/o error: {err}"),
Error::BadMagic => f.write_str("not a bison-db file: header magic did not match"),
Error::UnsupportedVersion(v) => {
write!(
f,
"on-disk format version {v} is newer than this build supports"
)
}
Error::Corrupt(what) => write!(f, "corrupt record: {what}"),
Error::ValueTooLarge => f.write_str("value exceeds the maximum record size"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Io(err) => Some(err),
_ => None,
}
}
}
#[cfg(not(feature = "std"))]
impl core::error::Error for Error {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_display_corrupt_includes_label() {
let err = Error::Corrupt("crc mismatch");
assert!(err.to_string().contains("crc mismatch"));
}
#[test]
fn test_display_unsupported_version_includes_number() {
let err = Error::UnsupportedVersion(9);
assert!(err.to_string().contains('9'));
}
#[cfg(feature = "std")]
#[test]
fn test_io_error_conversion_preserves_source() {
use std::error::Error as _;
let io = std::io::Error::other("disk on fire");
let err: Error = io.into();
assert!(err.source().is_some());
}
}