use std::path::PathBuf;
use fluent_i18n::t;
use crate::Architecture;
#[derive(Debug, thiserror::Error, PartialEq)]
pub enum Error {
#[error("{msg}", msg = t!("error-invalid-architectures", {
"architectures" => format!("{architectures:?}"),
"context" => context
}))]
InvalidArchitectures {
architectures: Vec<Architecture>,
context: &'static str,
},
#[error("{msg}", msg = t!("error-invalid-integer", { "kind" => format!("{kind:?}") }))]
InvalidInteger {
kind: std::num::IntErrorKind,
},
#[error("{msg}", msg = t!("error-invalid-variant", { "error" => .0.to_string() }))]
InvalidVariant(#[from] strum::ParseError),
#[error("{msg}", msg = t!("error-invalid-email", { "error" => .0.to_string() }))]
InvalidEmail(#[from] email_address::Error),
#[error("{msg}", msg = t!("error-invalid-url", { "error" => .0.to_string() }))]
InvalidUrl(#[from] url::ParseError),
#[error("{msg}", msg = t!("error-invalid-license", { "error" => .0.to_string() }))]
InvalidLicense(#[from] spdx::ParseError),
#[error("{msg}", msg = t!("error-invalid-semver", { "kind" => kind }))]
InvalidSemver {
kind: String,
},
#[error("{msg}", msg = t!("error-invalid-chars", { "invalid_char" => invalid_char.to_string() }))]
ValueContainsInvalidChars {
invalid_char: char,
},
#[error("{msg}", msg = t!("error-incorrect-length", { "length" => length, "expected" => expected }))]
IncorrectLength {
length: usize,
expected: usize,
},
#[error("{msg}", msg = t!("error-delimiter-not-found", { "delimiter" => delimiter.to_string() }))]
DelimiterNotFound {
delimiter: char,
},
#[error("{msg}", msg = t!("error-restrictions-not-met", {
"restrictions" => format!("{restrictions:?}")
}))]
ValueDoesNotMatchRestrictions {
restrictions: Vec<String>,
},
#[error("{msg}", msg = t!("error-regex-mismatch", {
"value" => value,
"regex_type" => regex_type,
"regex" => regex
}))]
RegexDoesNotMatch {
value: String,
regex_type: String,
regex: String,
},
#[error("{msg}", msg = t!("error-parse", { "error" => .0 }))]
ParseError(String),
#[error("{msg}", msg = t!("error-missing-component", { "component" => component }))]
MissingComponent {
component: &'static str,
},
#[error("{msg}", msg = t!("error-path-not-absolute", { "path" => .0 }))]
PathNotAbsolute(PathBuf),
#[error("{msg}", msg = t!("error-path-not-relative", { "path" => .0 }))]
PathNotRelative(PathBuf),
#[error("{msg}", msg = t!("error-path-not-file", { "path" => .0 }))]
PathIsNotAFile(PathBuf),
#[error("{msg}", msg = t!("error-filename-invalid-chars", {
"path" => .0,
"invalid_char" => .1.to_string()
}))]
FileNameContainsInvalidChars(PathBuf, char),
#[error("{msg}", msg = t!("error-filename-empty"))]
FileNameIsEmpty,
#[error("{msg}", msg = t!("error-deprecated-license", { "license" => .0 }))]
DeprecatedLicense(String),
#[error("{msg}", msg = t!("error-invalid-component", {
"component" => component,
"context" => context
}))]
InvalidComponent {
component: &'static str,
context: String,
},
#[error("{msg}", msg = t!("error-invalid-pgp-fingerprint"))]
InvalidOpenPGPv4Fingerprint,
#[error("{msg}", msg = t!("error-invalid-pgp-keyid", { "keyid" => .0 }))]
InvalidOpenPGPKeyId(String),
#[error("{msg}", msg = t!("error-invalid-base64-encoding", { "expected_item" => expected_item }))]
InvalidBase64Encoding {
expected_item: String,
},
#[error("{msg}", msg = t!("error-invalid-soname-v1", { "name" => .0 }))]
InvalidSonameV1(&'static str),
#[error("{msg}", msg = t!("error-package", { "error" => .0.to_string() }))]
Package(#[from] crate::PackageError),
#[error("{msg}", msg = t!("error-unknown-compression", { "value" => value }))]
UnknownCompressionAlgorithmFileExtension {
value: String,
},
#[error("{msg}", msg = t!("error-unknown-filetype", { "value" => value }))]
UnknownFileTypeIdentifier {
value: String,
},
}
impl From<std::num::ParseIntError> for crate::error::Error {
fn from(e: std::num::ParseIntError) -> Self {
Self::InvalidInteger { kind: *e.kind() }
}
}
impl<'a> From<winnow::error::ParseError<&'a str, winnow::error::ContextError>>
for crate::error::Error
{
fn from(value: winnow::error::ParseError<&'a str, winnow::error::ContextError>) -> Self {
Self::ParseError(value.to_string())
}
}
#[cfg(test)]
mod tests {
use std::num::IntErrorKind;
use rstest::rstest;
use super::*;
#[rstest]
#[case(
"Invalid integer (caused by InvalidDigit)",
Error::InvalidInteger {
kind: IntErrorKind::InvalidDigit
}
)]
#[case(
"Invalid integer (caused by InvalidDigit)",
Error::InvalidInteger {
kind: IntErrorKind::InvalidDigit
}
)]
#[case(
"Invalid integer (caused by PosOverflow)",
Error::InvalidInteger {
kind: IntErrorKind::PosOverflow
}
)]
#[allow(deprecated)]
#[case(
"Invalid integer (caused by InvalidDigit)",
Error::InvalidInteger {
kind: IntErrorKind::InvalidDigit
}
)]
#[case(
"Invalid e-mail (Missing separator character '@'.)",
email_address::Error::MissingSeparator.into()
)]
#[case(
"Invalid integer (caused by InvalidDigit)",
Error::InvalidInteger {
kind: IntErrorKind::InvalidDigit
}
)]
fn error_format_string(#[case] error_str: &str, #[case] error: Error) {
assert_eq!(error_str, format!("{error}"));
}
}