refactor(util-schemas): error type for PartialVersion

This commit is contained in:
Weihang Lo 2023-12-19 05:42:18 -05:00
parent da6cf9cde2
commit d7b811b686
No known key found for this signature in database
GPG key ID: D7DBF189825E82E7
2 changed files with 23 additions and 9 deletions

View file

@ -4,5 +4,6 @@ mod source_kind;
pub use package_id_spec::PackageIdSpec;
pub use partial_version::PartialVersion;
pub use partial_version::PartialVersionError;
pub use source_kind::GitReference;
pub use source_kind::SourceKind;

View file

@ -80,11 +80,11 @@ impl From<semver::Version> for PartialVersion {
}
impl std::str::FromStr for PartialVersion {
type Err = anyhow::Error;
type Err = PartialVersionError;
fn from_str(value: &str) -> Result<Self, Self::Err> {
if is_req(value) {
anyhow::bail!("unexpected version requirement, expected a version like \"1.32\"")
return Err(PartialVersionError::VersionReq);
}
match semver::Version::parse(value) {
Ok(ver) => Ok(ver.into()),
@ -92,15 +92,11 @@ impl std::str::FromStr for PartialVersion {
// HACK: Leverage `VersionReq` for partial version parsing
let mut version_req = match semver::VersionReq::parse(value) {
Ok(req) => req,
Err(_) if value.contains('-') => {
anyhow::bail!(
"unexpected prerelease field, expected a version like \"1.32\""
)
}
Err(_) if value.contains('-') => return Err(PartialVersionError::Prerelease),
Err(_) if value.contains('+') => {
anyhow::bail!("unexpected build field, expected a version like \"1.32\"")
return Err(PartialVersionError::BuildMetadata)
}
Err(_) => anyhow::bail!("expected a version like \"1.32\""),
Err(_) => return Err(PartialVersionError::Unexpected),
};
assert_eq!(version_req.comparators.len(), 1, "guaranteed by is_req");
let comp = version_req.comparators.pop().unwrap();
@ -163,6 +159,23 @@ impl<'de> serde::Deserialize<'de> for PartialVersion {
}
}
/// Error parsing a [`PartialVersion`].
#[non_exhaustive]
#[derive(Debug, thiserror::Error)]
pub enum PartialVersionError {
#[error("unexpected version requirement, expected a version like \"1.32\"")]
VersionReq,
#[error("unexpected prerelease field, expected a version like \"1.32\"")]
Prerelease,
#[error("unexpected build field, expected a version like \"1.32\"")]
BuildMetadata,
#[error("expected a version like \"1.32\"")]
Unexpected,
}
fn is_req(value: &str) -> bool {
let Some(first) = value.chars().next() else {
return false;