Add a separate dist-info name struct (#85)

This commit is contained in:
Charlie Marsh 2023-10-10 19:21:18 -04:00 committed by GitHub
parent d0764bdc23
commit c1fb698eae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 131 additions and 10 deletions

View file

@ -215,7 +215,7 @@ pub(crate) async fn sync(
printer,
" {} {}{}",
"+".green(),
wheel.name().white().bold(),
wheel.name().as_ref().white().bold(),
format!("@{}", wheel.version()).dimmed()
)?;
}

View file

@ -5,6 +5,7 @@ use anyhow::{anyhow, Result};
use pep440_rs::Version;
use puffin_client::File;
use puffin_package::dist_info_name::DistInfoName;
use puffin_package::package_name::PackageName;
use wheel_filename::WheelFilename;
@ -77,7 +78,7 @@ impl RemoteDistribution {
}
pub fn id(&self) -> String {
format!("{}-{}", self.name().replace('-', "_"), self.version())
format!("{}-{}", DistInfoName::from(self.name()), self.version())
}
}
@ -135,6 +136,6 @@ impl LocalDistribution {
}
pub fn id(&self) -> String {
format!("{}-{}", self.name().replace('-', "_"), self.version())
format!("{}-{}", DistInfoName::from(self.name()), self.version())
}
}

View file

@ -0,0 +1,77 @@
use std::fmt;
use std::fmt::{Display, Formatter};
use once_cell::sync::Lazy;
use regex::Regex;
use crate::package_name::PackageName;
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct DistInfoName(String);
impl Display for DistInfoName {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
static NAME_NORMALIZE: Lazy<Regex> = Lazy::new(|| Regex::new(r"[-_.]+").unwrap());
impl DistInfoName {
/// See: <https://packaging.python.org/en/latest/specifications/recording-installed-packages/#recording-installed-packages>
pub fn normalize(name: impl AsRef<str>) -> Self {
// TODO(charlie): Avoid allocating in the common case (when no normalization is required).
let mut normalized = NAME_NORMALIZE.replace_all(name.as_ref(), "_").to_string();
normalized.make_ascii_lowercase();
Self(normalized)
}
}
impl AsRef<str> for DistInfoName {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl From<&PackageName> for DistInfoName {
fn from(package_name: &PackageName) -> Self {
Self::normalize(package_name)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn normalize() {
assert_eq!(
DistInfoName::normalize("friendly-bard").as_ref(),
"friendly_bard"
);
assert_eq!(
DistInfoName::normalize("Friendly-Bard").as_ref(),
"friendly_bard"
);
assert_eq!(
DistInfoName::normalize("FRIENDLY-BARD").as_ref(),
"friendly_bard"
);
assert_eq!(
DistInfoName::normalize("friendly.bard").as_ref(),
"friendly_bard"
);
assert_eq!(
DistInfoName::normalize("friendly_bard").as_ref(),
"friendly_bard"
);
assert_eq!(
DistInfoName::normalize("friendly--bard").as_ref(),
"friendly_bard"
);
assert_eq!(
DistInfoName::normalize("FrIeNdLy-._.-bArD").as_ref(),
"friendly_bard"
);
}
}

View file

@ -1,3 +1,4 @@
pub mod dist_info_name;
pub mod metadata;
pub mod package_name;
pub mod requirements;

View file

@ -1,10 +1,11 @@
use std::fmt;
use std::fmt::{Display, Formatter};
use std::ops::Deref;
use once_cell::sync::Lazy;
use regex::Regex;
use crate::dist_info_name::DistInfoName;
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct PackageName(String);
@ -14,7 +15,7 @@ impl Display for PackageName {
}
}
static NAME_NORMALIZE: Lazy<Regex> = Lazy::new(|| Regex::new(r"[-_.]").unwrap());
static NAME_NORMALIZE: Lazy<Regex> = Lazy::new(|| Regex::new(r"[-_.]+").unwrap());
impl PackageName {
/// See: <https://packaging.python.org/en/latest/specifications/name-normalization/>
@ -26,10 +27,51 @@ impl PackageName {
}
}
impl Deref for PackageName {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
impl AsRef<str> for PackageName {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl From<DistInfoName> for PackageName {
fn from(dist_info_name: DistInfoName) -> Self {
Self::normalize(dist_info_name)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn normalize() {
assert_eq!(
PackageName::normalize("friendly-bard").as_ref(),
"friendly-bard"
);
assert_eq!(
PackageName::normalize("Friendly-Bard").as_ref(),
"friendly-bard"
);
assert_eq!(
PackageName::normalize("FRIENDLY-BARD").as_ref(),
"friendly-bard"
);
assert_eq!(
PackageName::normalize("friendly.bard").as_ref(),
"friendly-bard"
);
assert_eq!(
PackageName::normalize("friendly_bard").as_ref(),
"friendly-bard"
);
assert_eq!(
PackageName::normalize("friendly--bard").as_ref(),
"friendly-bard"
);
assert_eq!(
PackageName::normalize("FrIeNdLy-._.-bArD").as_ref(),
"friendly-bard"
);
}
}