#[derive(Debug)]
pub enum Error {
FileHeaderMismatch(Option<String>),
VersionMismatch(Option<Vec<u8>>),
NoData,
NoParentDir(String),
GVariantDeserialization(zvariant::Error),
SaltSizeMismatch(usize, u32),
WeakKey(WeakKeyError),
Io(std::io::Error),
MacError,
ChecksumMismatch,
HashedAttributeMac(String),
NoDataDir,
TargetFileChanged(String),
Portal(ashpd::Error),
InvalidItemIndex(usize),
Utf8(std::str::Utf8Error),
AlgorithmMismatch(u8),
IncorrectSecret,
PartiallyCorruptedKeyring {
valid_items: usize,
broken_items: usize,
},
Crypto(crate::crypto::Error),
Locked,
#[cfg(feature = "schema")]
Schema(crate::SchemaError),
}
impl From<zvariant::Error> for Error {
fn from(value: zvariant::Error) -> Self {
Self::GVariantDeserialization(value)
}
}
impl From<WeakKeyError> for Error {
fn from(value: WeakKeyError) -> Self {
Self::WeakKey(value)
}
}
impl From<std::io::Error> for Error {
fn from(value: std::io::Error) -> Self {
Self::Io(value)
}
}
impl From<std::str::Utf8Error> for Error {
fn from(value: std::str::Utf8Error) -> Self {
Self::Utf8(value)
}
}
impl From<ashpd::Error> for Error {
fn from(value: ashpd::Error) -> Self {
Self::Portal(value)
}
}
impl From<crate::crypto::Error> for Error {
fn from(value: crate::crypto::Error) -> Self {
Self::Crypto(value)
}
}
#[cfg(feature = "schema")]
impl From<crate::SchemaError> for Error {
fn from(value: crate::SchemaError) -> Self {
Self::Schema(value)
}
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::FileHeaderMismatch(e) => {
write!(f, "File header doesn't match FILE_HEADER {e:#?}")
}
Self::VersionMismatch(e) => write!(
f,
"Version doesn't match MAJOR_VERSION OR MICRO_VERSION {e:#?}",
),
Self::NoData => write!(f, "No data behind header and version bytes"),
Self::NoParentDir(e) => write!(f, "No Parent Directory {e}"),
Self::GVariantDeserialization(e) => write!(f, "Failed to deserialize {e}"),
Self::SaltSizeMismatch(arr, explicit) => write!(
f,
"Salt size is not as expected. Array: {arr}, Explicit: {explicit}"
),
Self::WeakKey(err) => write!(f, "{err}"),
Self::Io(e) => write!(f, "IO error {e}"),
Self::MacError => write!(f, "Mac digest is not equal to the expected value"),
Self::ChecksumMismatch => write!(f, "Checksum is not equal to the expected value"),
Self::HashedAttributeMac(e) => write!(f, "Failed to validate hashed attribute {e}"),
Self::NoDataDir => write!(f, "Couldn't retrieve XDG_DATA_DIR"),
Self::TargetFileChanged(e) => write!(f, "The target file has changed {e}"),
Self::Portal(e) => write!(f, "Portal communication failed {e}"),
Self::InvalidItemIndex(index) => {
write!(f, "The addressed item index {index} does not exist")
}
Self::Utf8(e) => write!(f, "UTF-8 encoding error {e}"),
Self::AlgorithmMismatch(e) => write!(f, "Unknown algorithm {e}"),
Self::IncorrectSecret => write!(f, "Incorrect secret"),
Self::PartiallyCorruptedKeyring {
valid_items,
broken_items,
} => write!(
f,
"Keyring partially corrupted: {valid_items} valid items, {broken_items} broken items",
),
Self::Crypto(e) => write!(f, "Failed to do a cryptography operation, {e}"),
Self::Locked => write!(f, "Keyring or item is locked"),
#[cfg(feature = "schema")]
Self::Schema(e) => write!(f, "Schema error: {e}"),
}
}
}
#[derive(Debug)]
pub struct InvalidItemError {
error: Error,
attribute_names: Vec<String>,
}
impl InvalidItemError {
pub(super) fn new(error: Error, attribute_names: Vec<String>) -> Self {
Self {
error,
attribute_names,
}
}
}
impl std::error::Error for InvalidItemError {}
impl std::fmt::Display for InvalidItemError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Invalid item: {:?}. Property names: {:?}",
self.error, self.attribute_names
)
}
}
#[derive(Debug, Copy, Clone)]
pub enum WeakKeyError {
IterationCountTooLow(u32),
SaltTooShort(usize),
PasswordTooShort(usize),
StrengthUnknown,
}
impl std::error::Error for WeakKeyError {}
impl std::fmt::Display for WeakKeyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::IterationCountTooLow(count) => write!(f, "Iteration count too low: {count}"),
Self::SaltTooShort(length) => write!(f, "Salt too short: {length}"),
Self::PasswordTooShort(length) => {
write!(f, "Password (secret from portal) too short: {length}")
}
Self::StrengthUnknown => write!(f, "Strength unknown"),
}
}
}