#[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, Default, Eq, PartialEq)]
pub struct DiffSnapshot {
title: String,
change_id: String,
rendered: String,
file_stats: Vec<DiffFileStat>,
}
impl DiffSnapshot {
#[must_use]
pub fn new(change_id: impl Into<String>, rendered: impl Into<String>) -> Self {
Self {
title: String::new(),
change_id: change_id.into(),
rendered: rendered.into(),
file_stats: Vec::new(),
}
}
#[must_use]
pub fn with_title(mut self, title: impl Into<String>) -> Self {
self.title = title.into();
self
}
#[must_use]
pub fn with_file_stats(mut self, file_stats: Vec<DiffFileStat>) -> Self {
self.file_stats = file_stats;
self
}
#[must_use]
pub fn title(&self) -> &str {
&self.title
}
#[must_use]
pub fn change_id(&self) -> &str {
&self.change_id
}
#[must_use]
pub fn rendered(&self) -> &str {
&self.rendered
}
#[must_use]
pub fn file_stats(&self) -> &[DiffFileStat] {
&self.file_stats
}
#[must_use]
pub fn into_parts(self) -> (String, String, String, Vec<DiffFileStat>) {
(self.title, self.change_id, self.rendered, self.file_stats)
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct DiffFileStat {
path: String,
added: usize,
removed: usize,
rendered: String,
}
impl DiffFileStat {
#[must_use]
pub fn new(path: impl Into<String>, added: usize, removed: usize) -> Self {
Self {
path: path.into(),
added,
removed,
rendered: String::new(),
}
}
#[must_use]
pub fn with_rendered(mut self, rendered: impl Into<String>) -> Self {
self.rendered = rendered.into();
self
}
#[must_use]
pub fn path(&self) -> &str {
&self.path
}
#[must_use]
pub const fn added(&self) -> usize {
self.added
}
#[must_use]
pub const fn removed(&self) -> usize {
self.removed
}
#[must_use]
pub fn rendered(&self) -> &str {
&self.rendered
}
}
#[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
}
}
}