#![allow(clippy::default_trait_access)]
use crate::schema::RoleType;
use crate::TargetName;
use snafu::{Backtrace, Snafu};
use std::fmt::{self, Debug, Display};
use std::path::PathBuf;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Snafu)]
#[snafu(visibility(pub(super)))]
#[non_exhaustive]
#[allow(missing_docs)]
pub enum Error {
#[snafu(display("Duplicate key ID: {}", keyid))]
DuplicateKeyId { keyid: String },
#[snafu(display("Duplicate role name: {}", name))]
DuplicateRoleName { name: String },
#[snafu(display("Failed to open '{}': {}", path.display(), source))]
FileOpen {
path: PathBuf,
source: std::io::Error,
backtrace: Backtrace,
},
#[snafu(display("Failed to read '{}': {}", path.display(), source))]
FileRead {
path: PathBuf,
source: std::io::Error,
backtrace: Backtrace,
},
#[snafu(display("Failed to parse path pattern '{}' as a glob: {}", pattern, source))]
Glob {
pattern: String,
source: globset::Error,
backtrace: Backtrace,
},
#[snafu(display("Invalid key ID {}: calculated {}", keyid, calculated))]
InvalidKeyId {
keyid: String,
calculated: String,
backtrace: Backtrace,
},
#[snafu(display("Invalid hex string: {}", source))]
HexDecode {
source: hex::FromHexError,
backtrace: Backtrace,
},
#[snafu(display("Failed to serialize {} to JSON: {}", what, source))]
JsonSerialization {
what: String,
source: serde_json::Error,
backtrace: Backtrace,
},
#[snafu(display("Role {} missing from root metadata", role))]
MissingRole {
role: RoleType,
backtrace: Backtrace,
},
#[snafu(display("Invalid PEM string: {}", source))]
PemDecode {
source: Compat<pem::PemError>,
backtrace: Backtrace,
},
#[snafu(display(
"Signature threshold of {} not met for role {} ({} valid signatures)",
threshold,
role,
valid,
))]
SignatureThreshold {
role: RoleType,
threshold: u64,
valid: u64,
backtrace: Backtrace,
},
#[snafu(display("Invalid SubjectPublicKeyInfo document"))]
SpkiDecode { backtrace: Backtrace },
#[snafu(display("TUF targets must be files, given: '{}'", path.display()))]
TargetNotAFile { path: PathBuf, backtrace: Backtrace },
#[snafu(display("Invalid file permissions from parent delegation: {}", child))]
UnmatchedPath { child: String },
#[snafu(display("Target file not delegated: {}", name.raw()))]
TargetNotFound { name: TargetName },
#[snafu(display("Delegation doesn't contain targets field"))]
NoTargets,
#[snafu(display("Targets doesn't contain delegations field"))]
NoDelegations,
#[snafu(display("Role not found: {}", name))]
RoleNotFound { name: String },
}
pub struct Compat<T>(pub T);
impl<T: Debug> Debug for Compat<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Debug::fmt(&self.0, f)
}
}
impl<T: Display> Display for Compat<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
}
}
impl<T: Debug + Display> std::error::Error for Compat<T> {}