use crate::parser::CommitMessage;
pub fn wrap_body_at_length(msg: &mut CommitMessage, width: usize) {
let mut wrapped_lines = Vec::new();
for line in &msg.body_lines {
if line.trim().is_empty() {
wrapped_lines.push(String::new());
} else if line.len() > width {
wrapped_lines.extend(wrap_line(line, width));
} else {
wrapped_lines.push(line.clone());
}
}
msg.body_lines = wrapped_lines;
}
fn wrap_line(line: &str, width: usize) -> Vec<String> {
let words: Vec<&str> = line.split_whitespace().collect();
let mut result = Vec::new();
let mut current_line = String::new();
for word in words {
if word.len() > width {
if !current_line.is_empty() {
result.push(current_line.clone());
current_line.clear();
}
result.push(word.to_string());
continue;
}
let test_line = if current_line.is_empty() {
word.to_string()
} else {
format!("{} {}", current_line, word)
};
if test_line.len() <= width {
current_line = test_line;
} else {
result.push(current_line.clone());
current_line = word.to_string();
}
}
if !current_line.is_empty() {
result.push(current_line);
}
if result.is_empty() {
result.push(String::new());
}
result
}
pub fn enforce_subject_length(msg: &mut CommitMessage, max_length: usize) {
if msg.subject.len() > max_length {
let subject_text = msg.subject.clone();
let words: Vec<&str> = subject_text.split_whitespace().collect();
let mut subject_words = Vec::new();
let mut overflow_words = Vec::new();
let mut current_len = 0;
let mut found_split = false;
for (i, word) in words.iter().enumerate() {
let word_len = word.len();
let space_len = if i > 0 { 1 } else { 0 };
if !found_split && current_len + space_len + word_len <= max_length {
subject_words.push(*word);
current_len += space_len + word_len;
} else {
found_split = true;
overflow_words.push(*word);
}
}
if !overflow_words.is_empty() {
msg.subject = subject_words.join(" ");
msg.body_lines.insert(0, overflow_words.join(" "));
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_wrap_line() {
let line = "This is a very long line that should be wrapped at seventy two characters to follow best practices";
let wrapped = wrap_line(line, 72);
assert!(wrapped.iter().all(|l| l.len() <= 72));
}
}