Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make names & emails ASCII-case-insensitive #67

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading