use std::collections::HashMap;
use metatheca::Uuid;
use crate::error::Result;
pub struct JotRow {
pub entry: Uuid,
pub profile: String,
pub id: i64,
pub ext: String,
pub created_at_ns: Option<i64>,
pub summary: String,
pub effective: cuj::facts::EffectiveIndex,
pub attachments: Vec<String>,
}
impl JotRow {
pub fn short_ref(&self, scope: Option<&str>) -> String {
match scope {
Some(p) if p == self.profile => format!("--{}", self.id),
_ => format!("--{}--{}", self.profile, self.id),
}
}
}
pub struct Snapshot {
pub rows: Vec<JotRow>,
pub by_entry: HashMap<Uuid, usize>,
pub by_ident: HashMap<(String, i64), usize>,
owner: HashMap<Uuid, Uuid>,
pub profiles: Vec<(String, usize)>,
pub configs: HashMap<String, cuj::facts::ProfileConfig>,
}
impl Snapshot {
pub fn build(app: &cuj::App) -> Result<Snapshot> {
let reads = app.reads(&cuj::Opts::default())?;
let mut rows = Vec::new();
for (entry, ident) in reads.list(None) {
let summary = cuj::queries::summary_line(&reads, entry);
let attachments = reads
.attachments_of(entry)
.iter()
.map(|(_, a)| a.filename.clone())
.collect();
rows.push(JotRow {
entry,
profile: ident.profile.clone(),
id: ident.id,
ext: ident.ext.clone(),
created_at_ns: reads.births.get(&entry).map(|b| b.created_at_ns),
summary,
effective: reads.effective(entry),
attachments,
});
}
let by_entry: HashMap<Uuid, usize> =
rows.iter().enumerate().map(|(i, r)| (r.entry, i)).collect();
let by_ident: HashMap<(String, i64), usize> = rows
.iter()
.enumerate()
.map(|(i, r)| ((r.profile.clone(), r.id), i))
.collect();
let mut owner = HashMap::new();
for (att_entry, att) in &reads.attachments {
if let Ok(jot) = Uuid::parse_str(&att.jot) {
owner.insert(*att_entry, jot);
}
}
for (x_entry, body, _) in &reads.extractions {
if let Some(jot) = Uuid::parse_str(&body.of)
.ok()
.and_then(|att| owner.get(&att).copied())
{
owner.insert(*x_entry, jot);
}
}
let mut profiles: Vec<(String, usize)> = reads
.profiles
.keys()
.map(|name| {
let n = rows.iter().filter(|r| &r.profile == name).count();
(name.clone(), n)
})
.collect();
profiles.sort();
let configs = reads
.profiles
.iter()
.map(|(name, (_, cfg))| (name.clone(), cfg.clone()))
.collect();
Ok(Snapshot {
rows,
by_entry,
by_ident,
owner,
profiles,
configs,
})
}
pub fn owning_row(&self, entry: Uuid) -> Option<usize> {
if let Some(i) = self.by_entry.get(&entry) {
return Some(*i);
}
self.owner
.get(&entry)
.and_then(|jot| self.by_entry.get(jot))
.copied()
}
}