Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1c768a5

Browse files
committed
add all docs (GitoxideLabs#366)
1 parent deaeb7d commit 1c768a5

6 files changed

Lines changed: 70 additions & 17 deletions

File tree

git-mailmap/src/entry.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use crate::Entry;
22
use bstr::BStr;
33

4+
/// Constructors indicating what kind of mapping is created.
5+
///
6+
/// Only these combinations of values are valid.
7+
#[allow(missing_docs)]
48
impl<'a> Entry<'a> {
59
pub fn change_name_by_email(proper_name: impl Into<&'a BStr>, commit_email: impl Into<&'a BStr>) -> Self {
610
Entry {

git-mailmap/src/lib.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,57 @@
11
#![forbid(unsafe_code)]
2-
#![deny(rust_2018_idioms)]
2+
#![deny(rust_2018_idioms, missing_docs)]
3+
//! [Parse][parse()] .mailmap files as used in git repositories and remap names and emails
4+
//! using an [accelerated data-structure][Snapshot].
35
46
use bstr::BStr;
57

8+
///
69
pub mod parse;
10+
11+
/// Parse the given `buf` of bytes line by line into mapping [Entries][Entry].
12+
///
13+
/// Errors may occour per line, but it's up to the caller to stop iteration when
14+
/// one is encountered.
715
pub fn parse(buf: &[u8]) -> parse::Lines<'_> {
816
parse::Lines::new(buf)
917
}
1018

19+
/// Similar to [parse()], but will skip all lines that didn't parse correctly, silently squelching all errors.
1120
pub fn parse_ignore_errors(buf: &[u8]) -> impl Iterator<Item = Entry<'_>> {
1221
parse(buf).filter_map(Result::ok)
1322
}
1423

1524
mod entry;
1625

26+
///
1727
pub mod snapshot;
1828

29+
/// A data-structure to efficiently store a list of entries for optimal, case-insensitive lookup by email and
30+
/// optionally name to find mappings to new names and/or emails.
31+
///
32+
/// The memory layout is efficient, even though lots of small allocations are performed to store strings of emails and names.
1933
#[derive(Default, Clone)]
2034
pub struct Snapshot {
2135
/// Sorted by `old_email`
2236
entries_by_old_email: Vec<snapshot::EmailEntry>,
2337
}
2438

39+
/// An typical entry of a mailmap, which always contains an `old_email` by which
40+
/// the mapping is performed to replace the given `new_name` and `new_email`.
41+
///
42+
/// Optionally, `old_name` is also used for lookup.
43+
///
44+
/// Typically created by [parse()].
2545
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy, Default)]
2646
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
2747
pub struct Entry<'a> {
2848
#[cfg_attr(feature = "serde1", serde(borrow))]
2949
/// The name to map to.
30-
pub new_name: Option<&'a BStr>,
50+
pub(crate) new_name: Option<&'a BStr>,
3151
/// The email map to.
32-
pub new_email: Option<&'a BStr>,
52+
pub(crate) new_email: Option<&'a BStr>,
3353
/// The name to look for and replace.
34-
pub old_name: Option<&'a BStr>,
54+
pub(crate) old_name: Option<&'a BStr>,
3555
/// The email to look for and replace.
36-
pub old_email: &'a BStr,
56+
pub(crate) old_email: &'a BStr,
3757
}

git-mailmap/src/parse.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ mod error {
33
use quick_error::quick_error;
44

55
quick_error! {
6+
/// The error returned by [`parse()`][crate::parse()].
67
#[derive(Debug)]
8+
#[allow(missing_docs)]
79
pub enum Error {
810
UnconsumedInput { line_number: usize, line: BString } {
911
display("Line {} has too many names or emails, or none at all: {}", line_number, line)
@@ -19,6 +21,7 @@ use crate::Entry;
1921
use bstr::{BStr, ByteSlice};
2022
pub use error::Error;
2123

24+
/// An iterator to parse mailmap lines on-demand.
2225
pub struct Lines<'a> {
2326
lines: bstr::Lines<'a>,
2427
line_no: usize,

git-mailmap/src/snapshot.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ use git_actor::SignatureRef;
44
use std::cmp::Ordering;
55
use std::ops::Deref;
66

7+
/// A resolved signature with borrowed fields for a mapped `name` and/or `email`.
78
pub struct ResolvedSignature<'a> {
9+
/// The mapped name.
810
pub name: Option<&'a BStr>,
11+
/// The mapped email.
912
pub email: Option<&'a BStr>,
1013
}
1114

@@ -165,16 +168,24 @@ impl<'a> From<crate::Entry<'a>> for EmailEntry {
165168
}
166169

167170
impl Snapshot {
171+
/// Create a new snapshot from the given bytes buffer, ignoring all parse errors that may occour on a line-by-line basis.
172+
///
173+
/// This is similar to what git does.
168174
pub fn from_bytes(buf: &[u8]) -> Self {
169175
Self::new(crate::parse_ignore_errors(buf))
170176
}
171177

178+
/// Create a new instance from `entries`.
179+
///
180+
/// These can be obtained using [crate::parse()].
172181
pub fn new<'a>(entries: impl IntoIterator<Item = crate::Entry<'a>>) -> Self {
173182
let mut snapshot = Self::default();
174183
snapshot.merge(entries);
175184
snapshot
176185
}
177186

187+
/// Merge the given `entries` into this instance, possibly overwriting existing mappings with
188+
/// new ones should they collide.
178189
pub fn merge<'a>(&mut self, entries: impl IntoIterator<Item = crate::Entry<'a>>) -> &mut Self {
179190
for entry in entries {
180191
let old_email: EncodedStringRef<'_> = entry.old_email.into();
@@ -195,6 +206,10 @@ impl Snapshot {
195206
self
196207
}
197208

209+
/// Try to resolve `signature` by its contained email and name and provide resolved/mapped names as reference.
210+
/// Return `None` if no such mapping was found.
211+
///
212+
/// This is the fastest possible lookup as there is no allocation.
198213
pub fn try_resolve_ref<'a>(&'a self, signature: &git_actor::SignatureRef<'_>) -> Option<ResolvedSignature<'a>> {
199214
let email: EncodedStringRef<'_> = signature.email.into();
200215
let pos = self
@@ -214,11 +229,19 @@ impl Snapshot {
214229
}
215230
}
216231

232+
/// Try to resolve `signature` by its contained email and name and provide resolved/mapped names as owned signature,
233+
/// with the mapped name and/or email replaced accordingly.
234+
///
235+
/// Return `None` if no such mapping was found.
217236
pub fn try_resolve(&self, signature: &git_actor::SignatureRef<'_>) -> Option<git_actor::Signature> {
218237
let new = self.try_resolve_ref(signature)?;
219238
enriched_signature(signature, new)
220239
}
221240

241+
/// Like [`try_resolve()`][Snapshot::try_resolve()], but always returns an owned signature, which might be a copy
242+
/// of `signature` if no mapping was found.
243+
///
244+
/// Note that this method will always allocate.
222245
pub fn resolve(&self, signature: &git_actor::SignatureRef<'_>) -> git_actor::Signature {
223246
self.try_resolve(signature).unwrap_or_else(|| signature.to_owned())
224247
}

git-mailmap/tests/fixtures/overwrite.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ B-overwritten <new-b-email-overwritten> <old-b-email>
99
C <new-c-email> old-C <old-c-email>
1010
C-overwritten <new-c-email-overwritten> old-C <old-c-email>
1111

12+
<new-d-email> <old-d-email>
13+
<new-d-email-overwritten> <old-d-email>

git-mailmap/tests/snapshot/mod.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,14 @@ fn try_resolve() {
5454
fn non_name_and_name_mappings_will_not_clash() {
5555
let entries = vec![
5656
// add mapping from email
57-
git_mailmap::Entry {
58-
new_name: Some("new-name".into()),
59-
new_email: Some("new-email".into()),
60-
old_name: None,
61-
old_email: "old-email".into(),
62-
},
57+
git_mailmap::Entry::change_name_and_email_by_email("new-name", "new-email", "old-email"),
6358
// add mapping from name and email
64-
git_mailmap::Entry {
65-
new_name: Some("other-new-name".into()),
66-
new_email: Some("other-new-email".into()),
67-
old_name: Some("old-name".into()),
68-
old_email: "old-email".into(),
69-
},
59+
git_mailmap::Entry::change_name_and_email_by_name_and_email(
60+
"other-new-name",
61+
"other-new-email",
62+
"old-name",
63+
"old-email",
64+
),
7065
];
7166
for entries in vec![entries.clone().into_iter().rev().collect::<Vec<_>>(), entries] {
7267
let snapshot = Snapshot::new(entries);
@@ -104,6 +99,12 @@ fn overwrite_entries() {
10499
Some(signature("C-overwritten", "new-c-email-overwritten")),
105100
"name and email by name and email"
106101
);
102+
103+
assert_eq!(
104+
snapshot.try_resolve(&signature("unchanged", "old-d-email").to_ref()),
105+
Some(signature("unchanged", "new-d-email-overwritten")),
106+
"email by email"
107+
);
107108
}
108109

109110
fn snapshot() -> Snapshot {

0 commit comments

Comments
 (0)