use crate::csaf::aggregation::revision_history::UnvalidatedCsafRevisionHistory;
use crate::csaf::traits::util::impl_str_field_getter;
use crate::csaf::types::csaf_datetime::{CsafDateTime, ValidCsafDateTime};
use crate::csaf::types::version_number::CsafVersionNumber;
use crate::csaf_traits::{GeneratorTrait, RevisionTrait};
use crate::schema::csaf2_0::schema::{
DocumentGenerator as DocumentGenerator20, DocumentStatus as DocumentStatus20, Revision as Revision20,
Tracking as Tracking20,
};
use crate::schema::csaf2_1::schema::{
DocumentGenerator as DocumentGenerator21, DocumentStatus as DocumentStatus21, Revision as Revision21,
Tracking as Tracking21,
};
use chrono::{DateTime, Utc};
pub type RevisionHistory = Vec<RevisionHistoryItem>;
#[derive(Clone)]
pub struct RevisionHistoryItem {
pub path_index: usize,
pub date_string: String,
pub date: DateTime<Utc>,
pub number: CsafVersionNumber,
pub valid_date: ValidCsafDateTime,
}
pub trait RevisionHistorySortable {
fn inplace_sort_by_date_then_number(&mut self);
fn inplace_sort_by_number(&mut self);
}
impl RevisionHistorySortable for RevisionHistory {
fn inplace_sort_by_date_then_number(&mut self) {
self.sort_unstable_by_key(|item| (item.date, item.number.clone()));
}
fn inplace_sort_by_number(&mut self) {
self.sort_unstable_by(|a, b| a.number.cmp(&b.number));
}
}
pub trait TrackingTrait {
type GeneratorType: GeneratorTrait;
type RevisionType: RevisionTrait;
fn get_current_release_date(&self) -> CsafDateTime;
fn get_initial_release_date(&self) -> CsafDateTime;
fn get_generator(&self) -> Option<&Self::GeneratorType>;
fn get_revision_history(&self) -> &Vec<Self::RevisionType>;
fn aggregate_revision_history(&self) -> UnvalidatedCsafRevisionHistory {
UnvalidatedCsafRevisionHistory::from(self.get_revision_history())
}
fn get_status(&self) -> DocumentStatus21;
fn get_id(&self) -> &str;
fn get_version(&self) -> CsafVersionNumber;
}
impl TrackingTrait for Tracking20 {
type GeneratorType = DocumentGenerator20;
type RevisionType = Revision20;
fn get_current_release_date(&self) -> CsafDateTime {
CsafDateTime::from(&self.current_release_date)
}
fn get_initial_release_date(&self) -> CsafDateTime {
CsafDateTime::from(&self.initial_release_date)
}
fn get_generator(&self) -> Option<&Self::GeneratorType> {
self.generator.as_ref()
}
fn get_revision_history(&self) -> &Vec<Self::RevisionType> {
&self.revision_history
}
fn get_status(&self) -> DocumentStatus21 {
match self.status {
DocumentStatus20::Draft => DocumentStatus21::Draft,
DocumentStatus20::Final => DocumentStatus21::Final,
DocumentStatus20::Interim => DocumentStatus21::Interim,
}
}
impl_str_field_getter!(get_id, id);
fn get_version(&self) -> CsafVersionNumber {
CsafVersionNumber::from(&self.version)
}
}
impl TrackingTrait for Tracking21 {
type GeneratorType = DocumentGenerator21;
type RevisionType = Revision21;
fn get_current_release_date(&self) -> CsafDateTime {
CsafDateTime::from(&self.current_release_date)
}
fn get_initial_release_date(&self) -> CsafDateTime {
CsafDateTime::from(&self.initial_release_date)
}
fn get_generator(&self) -> Option<&Self::GeneratorType> {
self.generator.as_ref()
}
fn get_revision_history(&self) -> &Vec<Self::RevisionType> {
&self.revision_history
}
fn get_status(&self) -> DocumentStatus21 {
self.status
}
impl_str_field_getter!(get_id, id);
fn get_version(&self) -> CsafVersionNumber {
CsafVersionNumber::from(&self.version)
}
}