use std::path::PathBuf;
#[derive(Debug, thiserror::Error, PartialEq)]
pub enum Error {
#[error("Invalid integer (caused by {kind:?})")]
InvalidInteger { kind: std::num::IntErrorKind },
#[error("Invalid variant ({0})")]
InvalidVariant(#[from] strum::ParseError),
#[error("Invalid e-mail ({0})")]
InvalidEmail(#[from] email_address::Error),
#[error("Invalid URL ({0})")]
InvalidUrl(#[from] url::ParseError),
#[error("Invalid license ({0})")]
InvalidLicense(#[from] spdx::ParseError),
#[error("Invalid semver ({kind})")]
InvalidSemver { kind: String },
#[error("Value contains invalid characters: {invalid_char:?}")]
ValueContainsInvalidChars { invalid_char: char },
#[error("Incorrect length, got {length} expected {expected}")]
IncorrectLength { length: usize, expected: usize },
#[error("Value is missing the required delimiter: {delimiter}")]
DelimiterNotFound { delimiter: char },
#[error("Does not match the restrictions ({restrictions:?})")]
ValueDoesNotMatchRestrictions { restrictions: Vec<String> },
#[error("Value '{value}' does not match the '{regex_type}' regex: {regex}")]
RegexDoesNotMatch {
value: String,
regex_type: String,
regex: String,
},
#[error("Missing component: {component}")]
MissingComponent { component: &'static str },
#[error("The path is not absolute: {0}")]
PathNotAbsolute(PathBuf),
#[error("The path is not relative: {0}")]
PathNotRelative(PathBuf),
#[error("File name ({0}) contains invalid characters: {1:?}")]
FileNameContainsInvalidChars(PathBuf, char),
#[error("File name is empty")]
FileNameIsEmpty,
#[error("Deprecated license: {0}")]
DeprecatedLicense(String),
#[error(
"Invalid OpenPGP v4 fingerprint, only 40 uppercase hexadecimal characters are allowed"
)]
InvalidOpenPGPv4Fingerprint,
}
#[cfg(test)]
mod tests {
use std::num::IntErrorKind;
use rstest::rstest;
use super::*;
use crate::{name::NAME_REGEX, openpgp::PACKAGER_REGEX};
#[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
}
)]
#[case(
"Value '€i²' does not match the 'pkgname' regex: ^[a-z\\d_@+]+[a-z\\d\\-._@+]*$",
Error::RegexDoesNotMatch {
value: "€i²".to_string(),
regex_type: "pkgname".to_string(),
regex: NAME_REGEX.to_string(),
}
)]
#[allow(deprecated)]
#[case(
"Invalid integer (caused by InvalidDigit)",
Error::InvalidInteger {
kind: IntErrorKind::InvalidDigit
}
)]
#[case(
"Value '€i²' does not match the 'packager' regex: ^(?P<name>[\\w\\s\\-().]+) <(?P<email>.*)>$",
Error::RegexDoesNotMatch {
value: "€i²".to_string(),
regex_type: "packager".to_string(),
regex: PACKAGER_REGEX.to_string(),
}
)]
#[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));
}
}