Skip to main content

hatchery_server/
m4a_gateway.rs

1//! Core's m4a letters: core talks to sessions only through its own in-process m4a mailbox
2//! engine (the hub messenger). `POST /v1/sessions/{id}/wake` sends a letter from the operator
3//! mailbox to the session's node naming the session; sessions close their run by sending
4//! `run.close <run_id> <review|done|failed|cancelled> [branch] [commit]` to the operator
5//! mailbox (door `task.close_run` stays as a fallback).
6
7/// `run.close <run_id> <status> [branch] [commit]`, first line only.
8#[derive(Debug, PartialEq, Eq)]
9pub struct CloseCmd {
10    pub run_id: i64,
11    pub status: String,
12    pub branch: Option<String>,
13    pub commit: Option<String>,
14}
15
16pub fn parse_close(body: &str) -> Option<CloseCmd> {
17    let line = body.lines().next()?.trim();
18    let mut w = line.split_whitespace();
19    if w.next()? != "run.close" {
20        return None;
21    }
22    let run_id = w.next()?.trim_start_matches('#').parse().ok()?;
23    let status = w.next()?.to_owned();
24    let clean = |s: &str| Some(s.to_owned()).filter(|s| s.len() <= 200 && !s.chars().any(char::is_control));
25    Some(CloseCmd { run_id, status, branch: w.next().and_then(clean), commit: w.next().and_then(clean) })
26}
27
28/// Strip a matrix-style `@nick:server` to `nick` for comparisons.
29pub fn bare_nick(n: &str) -> &str {
30    let n = n.trim_start_matches('@');
31    n.split(':').next().unwrap_or(n)
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn parses_close_letters() {
40        assert_eq!(parse_close("run.close 7 done feat/x abc123\nthanks"), Some(CloseCmd { run_id: 7, status: "done".into(), branch: Some("feat/x".into()), commit: Some("abc123".into()) }));
41        assert_eq!(parse_close("run.close #3 review").unwrap().run_id, 3);
42        assert!(parse_close("hello run.close 1 done").is_none());
43        assert!(parse_close("run.close x done").is_none());
44    }
45
46    #[test]
47    fn bare_nicks() {
48        assert_eq!(bare_nick("@s1:h"), "s1");
49    }
50}