use crate::{
entities::issue::{
Issue,
data::{label::Label, status::Status},
issue_operation::File,
},
replica::entity::{
id::entity_id::EntityId, identity::IdentityStub,
snapshot::timeline::history_step::HistoryStep, timestamp::TimeStamp,
},
};
#[derive(Debug)]
pub struct NonEmptyVec<T> {
first: T,
rest: Vec<T>,
}
impl<T: Clone> Clone for NonEmptyVec<T> {
fn clone(&self) -> Self {
Self {
first: self.first.clone(),
rest: self.rest.clone(),
}
}
}
impl<T> NonEmptyVec<T> {
pub(super) fn new(item: T) -> Self {
Self {
first: item,
rest: vec![],
}
}
pub fn first(&self) -> &T {
&self.first
}
pub fn last(&self) -> &T {
self.rest.last().unwrap_or(&self.first)
}
pub(super) fn push(&mut self, item: T) {
self.rest.push(item);
}
}
#[derive(Debug, Clone)]
pub enum IssueHistoryStep {
Comment(CommentItem),
Status(StatusHistoryStep),
Label(LabelHistoryStep),
Body(BodyHistoryStep),
Title(TitleHistoryStep),
}
impl HistoryStep for IssueHistoryStep {
fn author(&self) -> IdentityStub {
match self {
IssueHistoryStep::Comment(comment_item) => comment_item.history.first().author,
IssueHistoryStep::Status(status_history_step) => status_history_step.author,
IssueHistoryStep::Label(label_history_step) => label_history_step.author,
IssueHistoryStep::Body(body_history_step) => body_history_step.author,
IssueHistoryStep::Title(title_history_step) => title_history_step.author,
}
}
fn at(&self) -> TimeStamp {
match self {
IssueHistoryStep::Comment(comment_item) => comment_item.history.last().at,
IssueHistoryStep::Status(status_history_step) => status_history_step.at,
IssueHistoryStep::Label(label_history_step) => label_history_step.at,
IssueHistoryStep::Body(body_history_step) => body_history_step.at,
IssueHistoryStep::Title(title_history_step) => title_history_step.at,
}
}
}
#[derive(Debug, Clone)]
pub struct CommentItem {
pub(crate) id: EntityId<Issue>,
pub(crate) history: NonEmptyVec<CommentHistoryStep>,
}
#[derive(Debug, Clone)]
pub struct CommentHistoryStep {
pub author: IdentityStub,
pub message: String,
pub files: Vec<File>,
pub at: TimeStamp,
}
#[derive(Debug, Clone, Copy)]
pub struct StatusHistoryStep {
pub author: IdentityStub,
pub status: Status,
pub at: TimeStamp,
}
#[derive(Debug, Clone)]
pub struct LabelHistoryStep {
pub author: IdentityStub,
pub added: Vec<Label>,
pub removed: Vec<Label>,
pub at: TimeStamp,
}
#[derive(Debug, Clone)]
pub struct BodyHistoryStep {
pub author: IdentityStub,
pub message: String,
pub files: Vec<File>,
pub at: TimeStamp,
}
#[derive(Debug, Clone)]
pub struct TitleHistoryStep {
pub author: IdentityStub,
pub title: String,
pub at: TimeStamp,
}