use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error("invalid {data_type} size: expected {expected}, got {actual}")]
InvalidSize {
data_type: String,
expected: usize,
actual: usize,
},
#[error("invalid {data_type}: {reason}")]
InvalidData { data_type: String, reason: String },
#[error(
"data too short: {data_type} expected at least {minimum}, got {actual}"
)]
DataTooShort {
data_type: String,
minimum: usize,
actual: usize,
},
#[error("cryptographic operation failed: {0}")]
Crypto(String),
#[error("CBOR error: {0}")]
Cbor(#[from] dcbor::Error),
#[error("SSKR error: {0}")]
Sskr(#[from] sskr::Error),
#[error("SSH operation failed: {0}")]
Ssh(String),
#[error("invalid URI: {0}")]
Uri(#[from] url::ParseError),
#[error("compression error: {0}")]
Compression(String),
#[error("post-quantum cryptography error: {0}")]
PostQuantum(String),
#[error("signature level does not match key level")]
LevelMismatch,
#[error("SSH agent error: {0}")]
SshAgent(String),
#[error("hex decoding error: {0}")]
Hex(#[from] hex::FromHexError),
#[error("UTF-8 conversion error: {0}")]
Utf8(#[from] std::string::FromUtf8Error),
#[error("environment variable error: {0}")]
Env(#[from] std::env::VarError),
#[error("SSH agent client error: {0}")]
SshAgentClient(String),
#[error("{0}")]
General(String),
}
impl Error {
pub fn general(msg: impl Into<String>) -> Self {
Error::General(msg.into())
}
pub fn invalid_size(
data_type: impl Into<String>,
expected: usize,
actual: usize,
) -> Self {
Error::InvalidSize { data_type: data_type.into(), expected, actual }
}
pub fn invalid_data(
data_type: impl Into<String>,
reason: impl Into<String>,
) -> Self {
Error::InvalidData {
data_type: data_type.into(),
reason: reason.into(),
}
}
pub fn data_too_short(
data_type: impl Into<String>,
minimum: usize,
actual: usize,
) -> Self {
Error::DataTooShort { data_type: data_type.into(), minimum, actual }
}
pub fn crypto(msg: impl Into<String>) -> Self { Error::Crypto(msg.into()) }
pub fn ssh(msg: impl Into<String>) -> Self { Error::Ssh(msg.into()) }
pub fn compression(msg: impl Into<String>) -> Self {
Error::Compression(msg.into())
}
pub fn post_quantum(msg: impl Into<String>) -> Self {
Error::PostQuantum(msg.into())
}
pub fn ssh_agent(msg: impl Into<String>) -> Self {
Error::SshAgent(msg.into())
}
pub fn ssh_agent_client(msg: impl Into<String>) -> Self {
Error::SshAgentClient(msg.into())
}
}
impl From<Error> for dcbor::Error {
fn from(err: Error) -> Self {
match err {
Error::Cbor(cbor_err) => cbor_err,
_ => dcbor::Error::msg(err.to_string()),
}
}
}
#[cfg(feature = "ssh-agent")]
impl From<ssh_agent_client_rs::Error> for Error {
fn from(err: ssh_agent_client_rs::Error) -> Self {
Error::ssh_agent_client(err.to_string())
}
}
#[cfg(feature = "ssh")]
impl From<ssh_key::Error> for Error {
fn from(err: ssh_key::Error) -> Self { Error::ssh(err.to_string()) }
}
impl From<bc_crypto::Error> for Error {
fn from(err: bc_crypto::Error) -> Self { Error::crypto(err.to_string()) }
}
pub type Result<T> = std::result::Result<T, Error>;