Skip to content

Instantly share code, notes, and snippets.

@PurpleBooth
Last active July 4, 2018 22:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PurpleBooth/663be4a3b931b475d4620fee58e6ad3d to your computer and use it in GitHub Desktop.
Save PurpleBooth/663be4a3b931b475d4620fee58e6ad3d to your computer and use it in GitHub Desktop.
If dodging.
pub fn validate_commit(message: &str) -> Result<&str, &str> {
check_gap_between_subject_and_body(message)
.and_then(check_subject_line_longer_than_50_characters)
.and_then(check_body_line_longer_than_72_characters)
}
fn check_gap_between_subject_and_body(message: &str) -> Result<&str, &str> {
has_one_line(message)
.or_else(|| has_empty_second_line(message))
.ok_or("No gap between subject and body.")
}
fn has_empty_second_line(message: &str) -> Option<&str> {
message
.lines()
.nth(1)
.filter(|l| l.is_empty())
.map(|_| message)
}
fn has_one_line(message: &str) -> Option<&str> {
message
.lines()
.try_fold(0i32, |acc, _| acc.checked_add(1))
.filter(|c| c == &1)
.map(|_| message)
}
fn check_subject_line_longer_than_50_characters(message: &str) -> Result<&str, &str> {
message
.lines()
.nth(0)
.filter(|l| (l.len() < 50))
.map(|_| message)
.ok_or("Subject line longer than 50 characters.")
}
fn check_body_line_longer_than_72_characters(message: &str) -> Result<&str, &str> {
message
.lines()
.skip(2)
.filter(|l| l.len() >= 72)
.try_fold(0i32, |acc, _| acc.checked_add(1))
.filter(|c| c < &1)
.map(|_| message)
.ok_or("Body line longer than 72 characters.")
}
#[cfg(test)]
mod tests {
use validate_commit;
#[test]
fn it_returns_ok_for_well_formatted_commit() {
let commit_message = r#"Short (50 chars or less) summary of changes
More detailed explanatory text, if necessary. Wrap it to
about 72 characters or so. In some contexts, the first
line is treated as the subject of an email and the rest of
the text as the body. The blank line separating the
summary from the body is critical (unless you omit the body
entirely); tools like rebase can get confused if you run
the two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet,
preceded by a single space, with blank lines in
between, but conventions vary here"#;
assert_eq!(Ok(commit_message), validate_commit(commit_message));
}
#[test]
fn it_returns_ok_for_well_formatted_short_commit() {
let commit_message = r#"Short (50 chars or less) summary of changes"#;
assert_eq!(Ok(commit_message), validate_commit(commit_message));
}
#[test]
fn it_returns_err_for_body_longer_than_72_characters() {
let commit_message = r#"Short (50 chars or less) summary of changes
This is far far far far far far far far far far far far far far too long to be valid
More detailed explanatory text, if necessary. Wrap it to
about 72 characters or so. In some contexts, the first
line is treated as the subject of an email and the rest of
the text as the body. The blank line separating the
summary from the body is critical (unless you omit the body
entirely); tools like rebase can get confused if you run
the two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet,
preceded by a single space, with blank lines in
between, but conventions vary here"#;
assert_eq!(
Err("Body line longer than 72 characters."),
validate_commit(commit_message)
);
}
#[test]
fn it_returns_err_for_subject_longer_than_50_characters() {
let commit_message = r#"This is far far far far far far far far far too long to be valid
More detailed explanatory text, if necessary. Wrap it to
about 72 characters or so. In some contexts, the first
line is treated as the subject of an email and the rest of
the text as the body. The blank line separating the
summary from the body is critical (unless you omit the body
entirely); tools like rebase can get confused if you run
the two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet,
preceded by a single space, with blank lines in
between, but conventions vary here"#;
assert_eq!(
Err("Subject line longer than 50 characters."),
validate_commit(commit_message)
);
}
#[test]
fn it_returns_err_for_no_gap_between_subject_and_body() {
let commit_message = r#"Short (50 chars or less) summary of changes
More detailed explanatory text, if necessary. Wrap it to
about 72 characters or so. In some contexts, the first
line is treated as the subject of an email and the rest of
the text as the body. The blank line separating the
summary from the body is critical (unless you omit the body
entirely); tools like rebase can get confused if you run
the two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet,
preceded by a single space, with blank lines in
between, but conventions vary here"#;
assert_eq!(
Err("No gap between subject and body."),
validate_commit(commit_message)
);
}
}
@PurpleBooth
Copy link
Author

PurpleBooth commented Jul 4, 2018

I guess this is clearer

fn check_gap_between_subject_and_body(message: &str) -> Result<&str, &str> {
    if has_one_line(message) || has_empty_second_line(message) {
        return Ok(message);
    }

    Err("No gap between subject and body.")
}

fn has_empty_second_line(message: &str) -> bool {
    message
        .lines()
        .nth(1)
        .filter(|l| l.is_empty())
        .is_some()
}

fn has_one_line(message: &str) -> bool {
    message
        .lines()
        .try_fold(0i32, |acc, _| acc.checked_add(1))
        .filter(|c| c == &1)
        .is_some()
}

But it uses if's

@PurpleBooth
Copy link
Author

Again, this looks clearer too, but contains if's

fn check_body_line_longer_than_72_characters(message: &str) -> Result<&str, &str> {
    if message
        .lines()
        .skip(2)
        .all(|l| l.len() < 72) {
        return Ok(message);
    }

    Err("Body line longer than 72 characters.")
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment