Skip to content

Commit

Permalink
Make names & emails ASCII-case-insensitive
Browse files Browse the repository at this point in the history
  • Loading branch information
GrigorenkoPV committed Aug 14, 2024
1 parent 5b2c975 commit 0574a0f
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 38 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions mailmap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ categories = ["parsing"]
license = "MIT OR Apache-2.0"

[dependencies]
uncased = "0.9.10"
56 changes: 37 additions & 19 deletions mailmap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use std::fmt;
use std::pin::Pin;
use std::ptr::NonNull;

use uncased::{Uncased, UncasedStr};

#[cfg(test)]
mod test;

Expand Down Expand Up @@ -36,10 +38,10 @@ impl fmt::Debug for Mailmap {

#[derive(Copy, Clone)]
struct RawMapEntry {
canonical_name: Option<NonNull<str>>,
canonical_email: Option<NonNull<str>>,
current_name: Option<NonNull<str>>,
current_email: Option<NonNull<str>>,
canonical_name: Option<NonNull<UncasedStr>>,
canonical_email: Option<NonNull<UncasedStr>>,
current_name: Option<NonNull<UncasedStr>>,
current_email: Option<NonNull<UncasedStr>>,
}

impl RawMapEntry {
Expand All @@ -55,10 +57,10 @@ impl RawMapEntry {

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
struct MapEntry<'a> {
canonical_name: Option<&'a str>,
canonical_email: Option<&'a str>,
current_name: Option<&'a str>,
current_email: Option<&'a str>,
canonical_name: Option<&'a UncasedStr>,
canonical_email: Option<&'a UncasedStr>,
current_name: Option<&'a UncasedStr>,
current_email: Option<&'a UncasedStr>,
}

impl<'a> MapEntry<'a> {
Expand All @@ -74,8 +76,8 @@ impl<'a> MapEntry<'a> {

#[derive(Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub struct Author {
pub name: String,
pub email: String,
pub name: Uncased<'static>,
pub email: Uncased<'static>,
}

impl fmt::Debug for Author {
Expand Down Expand Up @@ -107,15 +109,31 @@ impl Mailmap {
if let Some(name) = entry.current_name {
if author.name == name && author.email == email {
return Author {
name: entry.canonical_name.unwrap_or(&author.name).to_owned(),
email: entry.canonical_email.expect("canonical email").to_owned(),
name: entry
.canonical_name
.unwrap_or(&author.name)
.to_string()
.into(),
email: entry
.canonical_email
.expect("canonical email")
.to_string()
.into(),
};
}
} else {
if author.email == email {
return Author {
name: entry.canonical_name.unwrap_or(&author.name).to_owned(),
email: entry.canonical_email.expect("canonical email").to_owned(),
name: entry
.canonical_name
.unwrap_or(&author.name)
.to_string()
.into(),
email: entry
.canonical_email
.expect("canonical email")
.to_string()
.into(),
};
}
}
Expand All @@ -126,7 +144,7 @@ impl Mailmap {
}
}

fn read_email<'a>(line: &mut &'a str) -> Option<&'a str> {
fn read_email<'a>(line: &mut &'a str) -> Option<&'a UncasedStr> {
if !line.starts_with('<') {
return None;
}
Expand All @@ -136,21 +154,21 @@ fn read_email<'a>(line: &mut &'a str) -> Option<&'a str> {
.unwrap_or_else(|| panic!("could not find email end in {:?}", line));
let ret = &line[1..end];
*line = &line[end + 1..];
Some(ret)
Some(ret.into())
}

fn read_name<'a>(line: &mut &'a str) -> Option<&'a str> {
fn read_name<'a>(line: &mut &'a str) -> Option<&'a UncasedStr> {
let end = if let Some(end) = line.find('<') {
end
} else {
return None;
};
let ret = &line[..end].trim();
let ret = line[..end].trim();
*line = &line[end..];
if ret.is_empty() {
None
} else {
Some(ret)
Some(ret.into())
}
}

Expand Down
31 changes: 20 additions & 11 deletions mailmap/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn comment_2() {
fn email_1() {
assert_eq!(
test_parser!(read_email, "<[email protected]>", ""),
Some("[email protected]")
Some("[email protected]".into())
);
}

Expand All @@ -35,7 +35,7 @@ fn email_2() {
"<[email protected]> <[email protected]>",
" <[email protected]>"
),
Some("[email protected]")
Some("[email protected]".into())
);
}

Expand All @@ -59,7 +59,7 @@ fn name_1() {
"Canonical Name <[email protected]>",
"<[email protected]>"
),
Some("Canonical Name"),
Some("Canonical Name".into()),
);
}

Expand All @@ -68,10 +68,10 @@ fn line_1() {
assert_eq!(
parse_line("Joe Bob <email1> <email2>", 0),
Some(MapEntry {
canonical_name: Some("Joe Bob"),
canonical_email: Some("email1"),
canonical_name: Some("Joe Bob".into()),
canonical_email: Some("email1".into()),
current_name: None,
current_email: Some("email2"),
current_email: Some("email2".into()),
})
);
}
Expand All @@ -81,18 +81,18 @@ fn line_2() {
assert_eq!(
parse_line("Joe Bob <email1>", 0),
Some(MapEntry {
canonical_name: Some("Joe Bob"),
canonical_email: Some("email1"),
canonical_name: Some("Joe Bob".into()),
canonical_email: Some("email1".into()),
current_name: None,
current_email: Some("email1"),
current_email: Some("email1".into()),
})
);
}

fn a(name: &str, email: &str) -> Author {
Author {
name: name.into(),
email: email.into(),
name: name.to_owned().into(),
email: email.to_owned().into(),
}
}

Expand Down Expand Up @@ -123,3 +123,12 @@ fn map_4() {
let mm = map("<PE> <CE>");
assert_eq!(mm.canonicalize(&a("any", "CE")), a("any", "PE"));
}

#[test]
fn case_insensitive() {
let mm = map("Proper Name <[email protected]> CoMmIt NaMe <[email protected]>");
assert_eq!(
mm.canonicalize(&a("Commit Name", "[email protected]")),
a("Proper Name", "[email protected]")
);
}
10 changes: 5 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ impl ToAuthor for Author {
.unwrap_or_else(|| panic!("no email for {}", sig));

Author {
name: name.to_string(),
email: email.to_string(),
name: name.to_string().into(),
email: email.to_string().into(),
}
}
}
Expand Down Expand Up @@ -259,8 +259,8 @@ fn commit_coauthors(commit: &Commit) -> Vec<Author> {
if line.starts_with("Co-authored-by") {
if let Some(caps) = RE.captures(line) {
coauthors.push(Author {
name: caps["name"].to_string(),
email: caps["email"].to_string(),
name: caps["name"].to_string().into(),
email: caps["email"].to_string().into(),
});
}
}
Expand Down Expand Up @@ -589,7 +589,7 @@ fn main() {
eprintln!("\tcaused by: {}", cause);
cur = cause;
}
std::mem::drop(cur);
let _ = cur;
std::process::exit(1);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/reviewers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ impl Reviewers {

fn a(name: &str, email: &str) -> Author {
Author {
name: name.into(),
email: email.into(),
name: name.to_string().into(),
email: email.to_string().into(),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ fn author_map_to_scores(map: &AuthorMap) -> Vec<Entry> {
.iter()
.map(|(author, commits)| Entry {
rank: 0,
author: author.name.clone(),
author: author.name.to_string(),
commits: commits,
})
.collect::<Vec<_>>();
Expand Down

0 comments on commit 0574a0f

Please sign in to comment.