gatewayd: a turn's speaker, the username of the one person who wrote its burst

Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
2026-09-28 10:51:17 -07:00
co-authored by ornith-1.5-35b-a3b
parent 4866353ac9
commit fae12c3fe2
12 changed files with 503 additions and 15 deletions
+26
View File
@@ -39,6 +39,8 @@ pub struct Message {
pub text: String,
/// A thread in a channel or group message that this Boxmaker now takes part in.
pub joins_thread: bool,
/// Who wrote it: the post's `user_id`, a Mattermost user id.
pub user: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -245,6 +247,7 @@ impl Router {
resume: !post.root_id.is_empty(),
text: format!("!{rest}"),
joins_thread: channel_type != "D",
user: post.user_id.clone(),
});
}
if let Some(command) = approval_command(message) {
@@ -269,6 +272,7 @@ impl Router {
resume: !post.root_id.is_empty(),
text: message.to_string(),
joins_thread: channel_type != "D",
user: post.user_id.clone(),
})
}
}
@@ -280,6 +284,22 @@ pub struct Batch {
pub thread: Thread,
pub resume: bool,
pub text: String,
/// Who wrote each message of `text`, in order: Mattermost user ids.
pub senders: Vec<String>,
}
impl Batch {
/// The one user who wrote every message of the batch. `None` when two or more people did, or
/// when it names nobody: a burst joined from several people has no speaker (M5c spec,
/// section 4).
pub fn sender(&self) -> Option<&str> {
let first = self.senders.first()?;
if self.senders.iter().all(|user| user == first) {
Some(first.as_str())
} else {
None
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -295,6 +315,8 @@ pub enum Pushed {
struct Pending {
thread: Thread,
waiting: Vec<String>,
/// The author of each message in `waiting`, in the same order.
senders: Vec<String>,
}
/// The sessions with a turn running, and the messages waiting for each.
@@ -323,6 +345,7 @@ impl Queues {
return Pushed::Full(pending.thread.clone());
}
pending.waiting.push(message.text.clone());
pending.senders.push(message.user.clone());
return Pushed::Waiting;
}
let batch = Batch {
@@ -330,12 +353,14 @@ impl Queues {
thread: message.thread.clone(),
resume: message.resume,
text: message.text.clone(),
senders: vec![message.user.clone()],
};
self.running.insert(
message.session,
Pending {
thread: message.thread.clone(),
waiting: Vec::new(),
senders: Vec::new(),
},
);
Pushed::Start(batch)
@@ -354,6 +379,7 @@ impl Queues {
thread: pending.thread.clone(),
resume: true,
text: pending.waiting.join("\n\n"),
senders: std::mem::take(&mut pending.senders),
};
pending.waiting.clear();
self.running.insert(session.clone(), pending);