use crate::git::repository::Repository;
use std::{error::Error, fmt::Display};
use tracing::trace;
#[derive(Debug, serde::Serialize)]
pub struct GitMessage {
pub title: String,
pub content: String,
}
impl Display for GitMessage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}\n\n{}", self.title, self.content)
}
}
impl GitMessage {
pub fn new(
repository: &Repository,
title: &str,
content: &str,
signoff: bool,
) -> Result<Self, Box<dyn Error>> {
let title_trimmed = title.trim();
let content_trimmed = content.trim();
if title_trimmed.is_empty() {
return Err("commit title cannot be empty".into());
}
if content_trimmed.is_empty() {
return Err("commit content cannot be empty".into());
}
let mut final_content = content_trimmed.to_string();
if signoff {
trace!("adding Signed-off-by line to commit message");
let author = repository.get_author()?;
final_content.push_str(&format!(
"\n\nSigned-off-by: {} <{}>",
author.name, author.email
));
}
trace!("created commit message with title: {}", title_trimmed);
trace!("content length: {} characters", final_content.len());
Ok(Self {
title: title_trimmed.to_string(),
content: final_content,
})
}
pub fn is_empty(&self) -> bool {
self.title.is_empty() && self.content.is_empty()
}
pub fn char_count(&self) -> usize {
self.title.len() + 2 + self.content.len() }
pub fn line_count(&self) -> usize {
1 + self.content.lines().count() }
}