diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /third_party/rust/lmdb-rkv/src/error.rs | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/lmdb-rkv/src/error.rs')
-rw-r--r-- | third_party/rust/lmdb-rkv/src/error.rs | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/third_party/rust/lmdb-rkv/src/error.rs b/third_party/rust/lmdb-rkv/src/error.rs new file mode 100644 index 0000000000..c13c970980 --- /dev/null +++ b/third_party/rust/lmdb-rkv/src/error.rs @@ -0,0 +1,156 @@ +use libc::c_int; +use std::error::Error as StdError; +use std::ffi::CStr; +use std::os::raw::c_char; +use std::{ + fmt, + result, + str, +}; + +use ffi; + +/// An LMDB error kind. +#[derive(Debug, Eq, PartialEq, Copy, Clone)] +pub enum Error { + /// key/data pair already exists. + KeyExist, + /// key/data pair not found (EOF). + NotFound, + /// Requested page not found - this usually indicates corruption. + PageNotFound, + /// Located page was wrong type. + Corrupted, + /// Update of meta page failed or environment had fatal error. + Panic, + /// Environment version mismatch. + VersionMismatch, + /// File is not a valid LMDB file. + Invalid, + /// Environment mapsize reached. + MapFull, + /// Environment maxdbs reached. + DbsFull, + /// Environment maxreaders reached. + ReadersFull, + /// Too many TLS keys in use - Windows only. + TlsFull, + /// Txn has too many dirty pages. + TxnFull, + /// Cursor stack too deep - internal error. + CursorFull, + /// Page has not enough space - internal error. + PageFull, + /// Database contents grew beyond environment mapsize. + MapResized, + /// MDB_Incompatible: Operation and DB incompatible, or DB flags changed. + Incompatible, + /// Invalid reuse of reader locktable slot. + BadRslot, + /// Transaction cannot recover - it must be aborted. + BadTxn, + /// Unsupported size of key/DB name/data, or wrong DUP_FIXED size. + BadValSize, + /// The specified DBI was changed unexpectedly. + BadDbi, + /// Other error. + Other(c_int), +} + +impl Error { + /// Converts a raw error code to an `Error`. + pub fn from_err_code(err_code: c_int) -> Error { + match err_code { + ffi::MDB_KEYEXIST => Error::KeyExist, + ffi::MDB_NOTFOUND => Error::NotFound, + ffi::MDB_PAGE_NOTFOUND => Error::PageNotFound, + ffi::MDB_CORRUPTED => Error::Corrupted, + ffi::MDB_PANIC => Error::Panic, + ffi::MDB_VERSION_MISMATCH => Error::VersionMismatch, + ffi::MDB_INVALID => Error::Invalid, + ffi::MDB_MAP_FULL => Error::MapFull, + ffi::MDB_DBS_FULL => Error::DbsFull, + ffi::MDB_READERS_FULL => Error::ReadersFull, + ffi::MDB_TLS_FULL => Error::TlsFull, + ffi::MDB_TXN_FULL => Error::TxnFull, + ffi::MDB_CURSOR_FULL => Error::CursorFull, + ffi::MDB_PAGE_FULL => Error::PageFull, + ffi::MDB_MAP_RESIZED => Error::MapResized, + ffi::MDB_INCOMPATIBLE => Error::Incompatible, + ffi::MDB_BAD_RSLOT => Error::BadRslot, + ffi::MDB_BAD_TXN => Error::BadTxn, + ffi::MDB_BAD_VALSIZE => Error::BadValSize, + ffi::MDB_BAD_DBI => Error::BadDbi, + other => Error::Other(other), + } + } + + /// Converts an `Error` to the raw error code. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn to_err_code(&self) -> c_int { + match *self { + Error::KeyExist => ffi::MDB_KEYEXIST, + Error::NotFound => ffi::MDB_NOTFOUND, + Error::PageNotFound => ffi::MDB_PAGE_NOTFOUND, + Error::Corrupted => ffi::MDB_CORRUPTED, + Error::Panic => ffi::MDB_PANIC, + Error::VersionMismatch => ffi::MDB_VERSION_MISMATCH, + Error::Invalid => ffi::MDB_INVALID, + Error::MapFull => ffi::MDB_MAP_FULL, + Error::DbsFull => ffi::MDB_DBS_FULL, + Error::ReadersFull => ffi::MDB_READERS_FULL, + Error::TlsFull => ffi::MDB_TLS_FULL, + Error::TxnFull => ffi::MDB_TXN_FULL, + Error::CursorFull => ffi::MDB_CURSOR_FULL, + Error::PageFull => ffi::MDB_PAGE_FULL, + Error::MapResized => ffi::MDB_MAP_RESIZED, + Error::Incompatible => ffi::MDB_INCOMPATIBLE, + Error::BadRslot => ffi::MDB_BAD_RSLOT, + Error::BadTxn => ffi::MDB_BAD_TXN, + Error::BadValSize => ffi::MDB_BAD_VALSIZE, + Error::BadDbi => ffi::MDB_BAD_DBI, + Error::Other(err_code) => err_code, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{}", self.description()) + } +} + +impl StdError for Error { + fn description(&self) -> &str { + unsafe { + // This is safe since the error messages returned from mdb_strerror are static. + let err: *const c_char = ffi::mdb_strerror(self.to_err_code()) as *const c_char; + str::from_utf8_unchecked(CStr::from_ptr(err).to_bytes()) + } + } +} + +/// An LMDB result. +pub type Result<T> = result::Result<T, Error>; + +pub fn lmdb_result(err_code: c_int) -> Result<()> { + if err_code == ffi::MDB_SUCCESS { + Ok(()) + } else { + Err(Error::from_err_code(err_code)) + } +} + +#[cfg(test)] +mod test { + + use std::error::Error as StdError; + + use super::*; + + #[test] + fn test_description() { + assert_eq!("Permission denied", Error::from_err_code(13).description()); + assert_eq!("MDB_NOTFOUND: No matching key/data pair found", Error::NotFound.description()); + } +} |