use super::Snapshot;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum Target {
Conversation(String),
Agent(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct Echo {
pub(crate) ws: PathBuf,
pub(crate) target: Target,
pub(crate) born: Option<String>,
pub(crate) text: String,
pub(crate) held: Vec<held::HeldSend>,
pub(crate) baseline: usize,
pub(crate) queue_baseline: usize,
pub(crate) at_unix: i64,
}
impl Echo {
pub(crate) fn started(ws: &Path, conversation: &str, goal: &str, at_unix: i64) -> Self {
Self {
ws: ws.to_path_buf(),
target: Target::Conversation(conversation.to_owned()),
born: Some(conversation.to_owned()),
text: goal.to_owned(),
held: Vec::new(),
baseline: 0,
queue_baseline: 0,
at_unix,
}
}
pub(crate) fn messaged(
snap: &Snapshot,
ws: &Path,
agent: &str,
content: &str,
queued: usize,
at_unix: i64,
) -> Self {
let target = Target::Agent(agent.to_owned());
let baseline = index_of(snap, ws, &target)
.and_then(|i| snap.trees.get(ws)?.agents.get(i))
.map_or(0, |a| a.messages);
Self {
ws: ws.to_path_buf(),
target,
born: None,
text: content.to_owned(),
held: Vec::new(),
baseline,
queue_baseline: queued,
at_unix,
}
}
pub(crate) fn resolved(&self, derived: &Snapshot) -> Option<String> {
let Target::Conversation(_) = &self.target else {
return None;
};
let i = index_of(derived, &self.ws, &self.target)?;
Some(derived.trees.get(&self.ws)?.agents.get(i)?.agent_id.clone())
}
pub(crate) fn landed(&self, derived: &Snapshot) -> bool {
index_of(derived, &self.ws, &self.target)
.and_then(|i| derived.trees.get(&self.ws)?.agents.get(i))
.is_some_and(|a| a.messages > self.baseline)
}
pub(crate) fn deposited(&self, shown: usize) -> bool {
shown > self.queue_baseline
}
pub(crate) fn addresses(&self, agent: &str) -> bool {
match &self.target {
Target::Conversation(name) => name == agent,
Target::Agent(id) => id == agent,
}
}
pub(crate) fn pending_identity(&self) -> Option<(String, String)> {
let name = self.born.clone()?;
match &self.target {
Target::Conversation(_) => Some((name.clone(), name)),
Target::Agent(id) => Some((id.clone(), name)),
}
}
}
fn index_of(snap: &Snapshot, ws: &Path, target: &Target) -> Option<usize> {
snap.trees
.get(ws)?
.agents
.iter()
.position(|a| match target {
Target::Conversation(name) => a.name_fact().as_deref() == Some(name.as_str()),
Target::Agent(id) => &a.agent_id == id,
})
}
pub(crate) mod held;
mod pending;
mod fold;
pub(crate) use fold::compose;
pub(crate) mod rows;
mod seat;
#[cfg(test)]
mod tests;