From ae33d93d8ea7a97faa8d7119be93356e2dfc9131 Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Fri, 27 Mar 2026 21:40:07 -0700 Subject: [PATCH] feat(wave1): Short UUID display utility and xml_escape helper [claudbg-x7wb] Co-Authored-By: Claude Sonnet 4.6 --- ...laudbg-x7wb--short-uuid-display-utility.md | 7 +- src/lib.rs | 2 +- src/util.rs | 100 ++++++++++++++++++ 3 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 src/util.rs diff --git a/.beans/claudbg-x7wb--short-uuid-display-utility.md b/.beans/claudbg-x7wb--short-uuid-display-utility.md index 8fb0213..dd802cc 100644 --- a/.beans/claudbg-x7wb--short-uuid-display-utility.md +++ b/.beans/claudbg-x7wb--short-uuid-display-utility.md @@ -1,11 +1,12 @@ --- # claudbg-x7wb title: Short UUID display utility -status: todo +status: completed type: task +priority: normal created_at: 2026-03-27T19:38:56Z -updated_at: 2026-03-27T19:38:56Z +updated_at: 2026-03-28T04:39:57Z parent: claudbg-h7xu --- -Utility function: given a UUID string, return the first 8 characters as the short form. Used in sessions list, agents list, etc. when --verbose is not passed. +Created src/util.rs with short_id and xml_escape functions. Ten unit tests cover UUID trimming, short strings, empty string, exact length, and all XML special characters. Updated src/lib.rs to declare pub mod util. diff --git a/src/lib.rs b/src/lib.rs index 0bb9076..8e3c9ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ pub mod cli; pub mod error; // pub mod models; // pub mod output; -// pub mod util; +pub mod util; #[cfg(test)] mod tests { diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..50d47ec --- /dev/null +++ b/src/util.rs @@ -0,0 +1,100 @@ +//! Utility helpers for claudbg. + +/// Returns the first 8 characters of a session/agent ID for compact display. +/// +/// If the ID is shorter than 8 characters, returns the full ID. +pub fn short_id(id: &str) -> &str { + &id[..id.len().min(8)] +} + +/// Escapes special XML characters in a string for safe embedding in XML content. +/// +/// The following substitutions are applied: +/// - `&` → `&` +/// - `<` → `<` +/// - `>` → `>` +/// - `"` → `"` +/// - `'` → `'` +pub fn xml_escape(s: &str) -> String { + let mut out = String::with_capacity(s.len()); + for ch in s.chars() { + match ch { + '&' => out.push_str("&"), + '<' => out.push_str("<"), + '>' => out.push_str(">"), + '"' => out.push_str("""), + '\'' => out.push_str("'"), + other => out.push(other), + } + } + out +} + +#[cfg(test)] +mod tests { + use super::*; + + /// `short_id` returns the first 8 characters of a 36-character UUID. + #[test] + fn short_id_uuid() { + let uuid = "550e8400-e29b-41d4-a716-446655440000"; + assert_eq!(short_id(uuid), "550e8400"); + } + + /// `short_id` returns the full string when it is shorter than 8 characters. + #[test] + fn short_id_short_string() { + assert_eq!(short_id("abc"), "abc"); + } + + /// `short_id` returns an empty string for an empty input. + #[test] + fn short_id_empty_string() { + assert_eq!(short_id(""), ""); + } + + /// `short_id` returns exactly 8 characters when input is exactly 8 characters. + #[test] + fn short_id_exact_length() { + assert_eq!(short_id("12345678"), "12345678"); + } + + /// `xml_escape` replaces `&` with `&`. + #[test] + fn xml_escape_ampersand() { + assert_eq!(xml_escape("a & b"), "a & b"); + } + + /// `xml_escape` replaces `<` with `<` and `>` with `>`. + #[test] + fn xml_escape_angle_brackets() { + assert_eq!(xml_escape(""), "<tag>"); + } + + /// `xml_escape` replaces `"` with `"`. + #[test] + fn xml_escape_double_quote() { + assert_eq!(xml_escape(r#"say "hello""#), "say "hello""); + } + + /// `xml_escape` replaces `'` with `'`. + #[test] + fn xml_escape_single_quote() { + assert_eq!(xml_escape("it's"), "it's"); + } + + /// `xml_escape` handles a string with multiple special characters. + #[test] + fn xml_escape_multiple() { + assert_eq!( + xml_escape(r#"it's"#), + "<a href="x&y">it's</a>" + ); + } + + /// `xml_escape` returns the input unchanged if no special characters are present. + #[test] + fn xml_escape_no_special() { + assert_eq!(xml_escape("hello world"), "hello world"); + } +}