#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct LogSnapshot {
title: String,
rendered: String,
entries: Vec<LogEntry>,
}
impl LogSnapshot {
#[must_use]
pub fn new(rendered: impl Into<String>, entries: Vec<LogEntry>) -> Self {
Self {
title: String::new(),
rendered: rendered.into(),
entries,
}
}
#[must_use]
pub fn with_title(mut self, title: impl Into<String>) -> Self {
self.title = title.into();
self
}
#[must_use]
pub fn title(&self) -> &str {
&self.title
}
#[must_use]
pub fn rendered(&self) -> &str {
&self.rendered
}
#[must_use]
pub fn entries(&self) -> &[LogEntry] {
&self.entries
}
#[must_use]
pub fn into_parts(self) -> (String, String, Vec<LogEntry>) {
(self.title, self.rendered, self.entries)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct LogEntry {
change_id: String,
commit_id: String,
description: String,
details: String,
rendered_line: usize,
}
impl LogEntry {
#[must_use]
pub fn new(
change_id: impl Into<String>,
commit_id: impl Into<String>,
description: impl Into<String>,
) -> Self {
Self {
change_id: change_id.into(),
commit_id: commit_id.into(),
description: description.into(),
details: String::new(),
rendered_line: 0,
}
}
#[must_use]
pub fn with_details(mut self, details: impl Into<String>) -> Self {
self.details = details.into();
self
}
#[must_use]
pub const fn with_rendered_line(mut self, rendered_line: usize) -> Self {
self.rendered_line = rendered_line;
self
}
#[must_use]
pub fn change_id(&self) -> &str {
&self.change_id
}
#[must_use]
pub fn commit_id(&self) -> &str {
&self.commit_id
}
#[must_use]
pub fn description(&self) -> &str {
&self.description
}
#[must_use]
pub fn details(&self) -> &str {
&self.details
}
#[must_use]
pub const fn rendered_line(&self) -> usize {
self.rendered_line
}
#[must_use]
pub fn summary(&self) -> &str {
let first_line = self.description.lines().next().unwrap_or_default();
if first_line.is_empty() {
"(no description set)"
} else {
first_line
}
}
}