#[cfg(feature = "alloc")]
use alloc::string::FromUtf8Error;
#[cfg(feature = "alloc")]
use alloc::{borrow::ToOwned, format, string::String, vec::Vec};
use core::fmt;
#[cfg(feature = "alloc")]
use core::str;
use crate::raw::FstType;
#[non_exhaustive]
pub enum Error {
Version {
expected: u64,
got: u64,
},
Format {
size: usize,
},
ChecksumMismatch {
expected: u32,
got: u32,
},
ChecksumMissing,
#[cfg(feature = "alloc")]
DuplicateKey {
got: Vec<u8>,
},
#[cfg(feature = "alloc")]
OutOfOrder {
previous: Vec<u8>,
got: Vec<u8>,
},
WrongType {
expected: FstType,
got: FstType,
},
#[cfg(feature = "alloc")]
FromUtf8(FromUtf8Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
#[cfg(feature = "alloc")]
Error::FromUtf8(ref err) => err.fmt(f),
Error::Version { expected, got } => write!(
f,
"\
Error opening FST: expected API version {expected}, got API version {got}. \
It looks like the FST you're trying to open is either not an FST file or it \
was generated with a different version of the 'fst' crate. You'll either need \
to change the version of the 'fst' crate you're using, or re-generate the
FST."
),
Error::Format { size } => write!(
f,
"\
Error opening FST with size {size} bytes: An unknown error occurred. This \
usually means you're trying to read data that isn't actually an encoded FST."
),
Error::ChecksumMismatch { expected, got } => write!(
f,
"FST verification failed: expected checksum of {expected} but got {got}",
),
Error::ChecksumMissing => write!(
f,
"FST verification failed: FST does not contain a checksum",
),
#[cfg(feature = "alloc")]
Error::DuplicateKey { ref got } => write!(
f,
"Error inserting duplicate key: '{}'.",
format_bytes(got)
),
#[cfg(feature = "alloc")]
Error::OutOfOrder { ref previous, ref got } => write!(
f,
"\
Error inserting out-of-order key: '{}'. (Previous key was '{}'.) Keys must be \
inserted in lexicographic order.",
format_bytes(got),
format_bytes(previous)
),
Error::WrongType { expected, got } => write!(
f,
"\
Error opening FST: expected type '{expected}', got type '{got}'."
),
}
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
#[cfg(feature = "alloc")]
Error::FromUtf8(ref err) => Some(err),
_ => None,
}
}
}
#[cfg(not(feature = "std"))]
impl core::error::Error for Error {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match *self {
#[cfg(feature = "alloc")]
Error::FromUtf8(ref err) => Some(err),
_ => None,
}
}
}
#[cfg(feature = "alloc")]
impl From<FromUtf8Error> for Error {
#[inline]
fn from(err: FromUtf8Error) -> Error {
Error::FromUtf8(err)
}
}
#[cfg(feature = "alloc")]
fn format_bytes(bytes: &[u8]) -> String {
match str::from_utf8(bytes) {
Ok(s) => s.to_owned(),
Err(_) => format!("{bytes:?}"),
}
}