use crate::Credential;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("Platform secure storage failure")]
PlatformFailure(#[source] Box<dyn std::error::Error + Send + Sync>),
#[error("Couldn't access platform secure storage")]
NoStorageAccess(#[source] Box<dyn std::error::Error + Send + Sync>),
#[error("No matching entry found in secure storage")]
NoEntry,
#[error("Data is not UTF-8 encoded")]
BadEncoding(Vec<u8>),
#[error("Attribute '{0}' is longer than platform limit of {1} chars")]
TooLong(String, u32),
#[error("Attribute {0} is invalid: {1}")]
Invalid(String, String),
#[error("Entry is matched by multiple credentials: {0:?}")]
Ambiguous(Vec<Box<Credential>>),
#[error("No default credential builder is available; set one before creating entries")]
NoDefaultCredentialBuilder,
}
pub type Result<T> = std::result::Result<T, Error>;
pub fn decode_password(bytes: Vec<u8>) -> Result<String> {
String::from_utf8(bytes).map_err(|err| Error::BadEncoding(err.into_bytes()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bad_password() {
for bytes in [b"\x80".to_vec(), b"\xbf".to_vec(), b"\xed\xa0\xa0".to_vec()] {
match decode_password(bytes.clone()) {
Err(Error::BadEncoding(str)) => assert_eq!(str, bytes),
Err(other) => panic!("Bad password ({bytes:?}) decode gave wrong error: {other}"),
Ok(s) => panic!("Bad password ({bytes:?}) decode gave results: {s:?}"),
}
}
}
}