From 12a7a24694dddcb96202af36774b94766532f30a Mon Sep 17 00:00:00 2001 From: Emi Tatsuo Date: Wed, 16 Dec 2020 16:45:35 -0500 Subject: [PATCH] Split off DeserializeError into its own thing --- src/user_management/mod.rs | 85 +++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 14 deletions(-) diff --git a/src/user_management/mod.rs b/src/user_management/mod.rs index 8dd8a44..fe9141c 100644 --- a/src/user_management/mod.rs +++ b/src/user_management/mod.rs @@ -59,16 +59,13 @@ pub enum UserManagerError { /// There was an error deserializing from the database /// - /// This likely indicates that the database was generated with - /// a different version of the software than is curretly being used, either because - /// the UserData struct has changed, or because kochab itself has updated it's schema. + /// This likely indicates that the database was generated with a different version of + /// the software than is curretly being used, either because the UserData struct has + /// changed, or because kochab itself has updated it's schema. /// /// Recommended handling: Log a visible error and exit. Recommend seeking a database /// migration script or deleting the database - DeserializeBincodeError(bincode::Error), - - /// A different version of [`UserManagerError::DeserializeBincodeError`] - DeserializeUtf8Error(std::str::Utf8Error), + DeserializeError(DeserializeError), #[cfg(feature = "user_management_advanced")] /// There was an error hashing or checking the user's password. @@ -92,13 +89,13 @@ impl From for UserManagerError { impl From for UserManagerError { fn from(error: bincode::Error) -> Self { - Self::DeserializeBincodeError(error) + Self::DeserializeError(error.into()) } } impl From for UserManagerError { fn from(error: std::str::Utf8Error) -> Self { - Self::DeserializeUtf8Error(error) + Self::DeserializeError(error.into()) } } @@ -114,8 +111,7 @@ impl std::error::Error for UserManagerError { match self { Self::DatabaseError(e) => Some(e), Self::DatabaseTransactionError(e) => Some(e), - Self::DeserializeBincodeError(e) => Some(e), - Self::DeserializeUtf8Error(e) => Some(e), + Self::DeserializeError(e) => Some(e), #[cfg(feature = "user_management_advanced")] Self::Argon2Error(e) => Some(e), _ => None @@ -134,10 +130,8 @@ impl std::fmt::Display for UserManagerError { write!(f, "Error accessing the user database: {}", e), Self::DatabaseTransactionError(e) => write!(f, "Error accessing the user database: {}", e), - Self::DeserializeBincodeError(e) => + Self::DeserializeError(e) => write!(f, "Recieved messy data from database, possible corruption: {}", e), - Self::DeserializeUtf8Error(e) => - write!(f, "Recieved invalid UTF-8 from database, possible corruption: {}", e), #[cfg(feature = "user_management_advanced")] Self::Argon2Error(e) => write!(f, "Argon2 Error, likely malformed password hash, possible database corruption: {}", e), @@ -145,5 +139,68 @@ impl std::fmt::Display for UserManagerError { } } +#[derive(Debug)] +/// Indicates an error deserializing from the database +/// +/// This likely indicates that the database was generated with +/// a different version of the software than is curretly being used, either because +/// the UserData struct has changed, or because kochab itself has updated it's schema. +pub enum DeserializeError { + + /// There was an error deserializing an entire struct + /// + /// Most likely indicates that the struct itself changed, i.e. between versions. + StructError(bincode::Error), + + /// The was an error deserializing a userid + /// + /// Likely because too many bytes were received. If you are getting this, you are + /// likely using a pre-0.1.0 version of kochab, and should update to the latest + /// version, or you're using a database that was created by a version of kochab that + /// was released after the one you're currently using. However, as of right now, no + /// such release exists or is planned. + UidError(std::str::Utf8Error), + + /// There was an error deserializing a username + /// + /// Indicates data corruption or a misaligned database version + UsernameError(std::str::Utf8Error), +} + +impl From for DeserializeError { + fn from(error: bincode::Error) -> Self { + Self::StructError(error) + } +} + +impl From for DeserializeError { + fn from(error: std::str::Utf8Error) -> Self { + Self::UsernameError(error) + } +} + +impl std::error::Error for DeserializeError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::StructError(e) => Some(e), + Self::UidError(e) => Some(e), + Self::UsernameError(e) => Some(e), + } + } +} + +impl std::fmt::Display for DeserializeError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> { + match self { + Self::StructError(e) => + write!(f, "Failed to deserialize struct: {}", e), + Self::UidError(e) => + write!(f, "Got wrong number of bytes while deserializing user ID: {}", e), + Self::UsernameError(e) => + write!(f, "Got invalid UTF-8 instead of username: {}", e), + } + } +} + /// A result type returned by many methods within the [`user_management`] module pub type Result = std::result::Result;