use std::path::{Path, PathBuf};
use serde::Serialize;
use super::cursor::HistoryCursor;
use super::query::HistoryOrder;
use crate::model::{RevisionId, TrackId};
use crate::session::event::EventType;
use crate::session::{
ActorAttributesMap, DelegationMap, EventVerificationPolicy, RefFilterMode, RemovalPolicy,
TrustSet,
};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ReviewHistoryOptions {
pub(super) repo: PathBuf,
pub(super) revision_id: Option<RevisionId>,
pub(super) track: Option<String>,
pub(super) event_types: Vec<EventType>,
pub(super) ref_filter: Option<(String, RefFilterMode)>,
pub(super) include_body: bool,
pub(super) verification_policy: Option<EventVerificationPolicy>,
pub(super) trust_set: TrustSet,
pub(super) removal_policy: RemovalPolicy,
pub(super) actor_attributes: Option<ActorAttributesMap>,
pub(super) delegation_map: Option<DelegationMap>,
pub(super) read_for_display: bool,
pub(super) order: HistoryOrder,
pub(super) filter: Option<String>,
pub(super) limit: Option<usize>,
pub(super) cursor: Option<HistoryCursor>,
}
impl ReviewHistoryOptions {
pub fn new(repo: impl AsRef<Path>) -> Self {
Self {
repo: repo.as_ref().to_path_buf(),
revision_id: None,
track: None,
event_types: Vec::new(),
ref_filter: None,
include_body: false,
verification_policy: None,
trust_set: TrustSet::default(),
removal_policy: RemovalPolicy::default(),
actor_attributes: None,
delegation_map: None,
read_for_display: false,
order: HistoryOrder::Asc,
filter: None,
limit: None,
cursor: None,
}
}
pub fn with_ref_filter(mut self, name: impl Into<String>, mode: RefFilterMode) -> Self {
self.ref_filter = Some((name.into(), mode));
self
}
pub fn with_revision_id(mut self, revision_id: RevisionId) -> Self {
self.revision_id = Some(revision_id);
self
}
pub fn with_track(mut self, track: impl Into<String>) -> Self {
self.track = Some(track.into());
self
}
pub fn with_event_type(mut self, event_type: EventType) -> Self {
self.event_types.push(event_type);
self
}
pub fn with_include_body(mut self, include_body: bool) -> Self {
self.include_body = include_body;
self
}
pub fn with_verification_policy(mut self, policy: EventVerificationPolicy) -> Self {
self.verification_policy = Some(policy);
self
}
pub fn with_trust_set(mut self, trust_set: TrustSet) -> Self {
self.trust_set = trust_set;
self
}
pub fn with_removal_policy(mut self, removal_policy: RemovalPolicy) -> Self {
self.removal_policy = removal_policy;
self
}
pub fn with_actor_attributes(mut self, actor_attributes: Option<ActorAttributesMap>) -> Self {
self.actor_attributes = actor_attributes;
self
}
pub fn with_delegation_map(mut self, delegation_map: DelegationMap) -> Self {
self.delegation_map = Some(delegation_map);
self
}
pub fn with_read_for_display(mut self, value: bool) -> Self {
self.read_for_display = value;
self
}
pub fn with_order(mut self, order: HistoryOrder) -> Self {
self.order = order;
self
}
pub fn with_filter(mut self, filter: impl Into<String>) -> Self {
self.filter = Some(filter.into());
self
}
pub fn with_limit(mut self, limit: usize) -> Self {
self.limit = Some(limit);
self
}
pub fn with_cursor(mut self, cursor: HistoryCursor) -> Self {
self.cursor = Some(cursor);
self
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ReviewHistoryFilters {
#[serde(skip_serializing_if = "Option::is_none")]
pub revision_id: Option<RevisionId>,
#[serde(skip_serializing_if = "Option::is_none")]
pub track_id: Option<TrackId>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub event_types: Vec<EventType>,
pub include_body: bool,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::model::EventId;
#[test]
fn options_carry_limit_and_cursor() {
let cursor = HistoryCursor {
occurred_at: "unix-ms:1".into(),
event_id: EventId::new("evt:sha256:a"),
};
let opts = ReviewHistoryOptions::new("/repo")
.with_limit(10)
.with_cursor(cursor.clone());
assert_eq!(opts.limit, Some(10));
assert_eq!(opts.cursor, Some(cursor));
}
#[test]
fn options_default_to_no_window() {
let opts = ReviewHistoryOptions::new("/repo");
assert_eq!(opts.limit, None);
assert_eq!(opts.cursor, None);
}
#[test]
fn options_carry_order_and_filter() {
let opts = ReviewHistoryOptions::new("/repo")
.with_order(HistoryOrder::Desc)
.with_filter("type:observation");
assert_eq!(opts.order, HistoryOrder::Desc);
assert_eq!(opts.filter.as_deref(), Some("type:observation"));
}
}