mod items;
use std::path::{Path, PathBuf};
pub(crate) use items::attention_from_events;
pub use items::{
AttentionAssessmentRecord, AttentionDetail, AttentionFreshness, AttentionFreshnessState,
AttentionItem, AttentionProjection, AttentionTier,
};
use crate::error::Result;
use crate::model::RevisionId;
use crate::session::EventStore;
use crate::session::projection::freshness::event_set_hash_for_events;
use crate::session::projection::skipped_to_diagnostics;
use crate::session::state::ProjectionDiagnostic;
use crate::session::store::resolution::resolve_read_store;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AttentionListOptions {
repo: PathBuf,
revision: Option<RevisionId>,
}
impl AttentionListOptions {
pub fn new(repo: impl AsRef<Path>) -> Self {
Self {
repo: repo.as_ref().to_path_buf(),
revision: None,
}
}
pub fn with_revision(mut self, revision: RevisionId) -> Self {
self.revision = Some(revision);
self
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AttentionListResult {
pub event_set_hash: String,
pub event_count: usize,
pub revision: Option<RevisionId>,
pub items: Vec<AttentionItem>,
pub diagnostics: Vec<ProjectionDiagnostic>,
}
pub fn list_attention(options: AttentionListOptions) -> Result<AttentionListResult> {
let read_store = resolve_read_store(&options.repo)?;
let store = EventStore::from_backend(read_store.backend());
let (events, skipped) = store.list_events_lenient()?;
let event_set_hash = event_set_hash_for_events(&events)?;
let mut projection = attention_from_events(&events, options.revision.as_ref())?;
projection
.diagnostics
.extend(skipped_to_diagnostics(skipped));
Ok(AttentionListResult {
event_set_hash,
event_count: events.len(),
revision: options.revision,
items: projection.items,
diagnostics: projection.diagnostics,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn list_attention_over_empty_store_returns_well_formed_envelope() {
let repo = tempfile::tempdir().expect("tempdir");
std::process::Command::new("git")
.args(["init"])
.current_dir(repo.path())
.output()
.expect("git init");
let result = list_attention(AttentionListOptions::new(repo.path())).expect("list");
assert_eq!(result.event_count, 0);
assert!(result.items.is_empty());
assert!(result.diagnostics.is_empty());
assert!(!result.event_set_hash.is_empty());
}
}