Skip to main content

ninox_core/
lib.rs

1pub mod brain;
2pub mod client;
3pub mod config;
4pub mod events;
5pub mod github;
6pub mod harness;
7pub mod hooks;
8pub mod lifecycle;
9pub mod plugin;
10pub mod pty;
11pub mod store;
12pub mod tmux;
13pub mod types;
14
15pub use brain::{BrainEntry, BrainIndex, QueryFilters};
16pub use config::{AppConfig, ThemeVariant};
17pub use events::{Engine, Event};
18pub use store::Store;
19pub use types::*;
20
21/// Convert a name into a tmux/URL-safe session ID.
22///
23/// Lowercases, maps non-alphanumeric chars to hyphens, and collapses consecutive
24/// hyphens. Returns an empty string if the input contains no alphanumeric chars.
25///
26/// Examples: `"ATH-123 auth fix"` → `"ath-123-auth-fix"`, `"my feature"` → `"my-feature"`
27pub fn slugify(s: &str) -> String {
28    s.to_lowercase()
29        .chars()
30        .map(|c| if c.is_ascii_alphanumeric() { c } else { '-' })
31        .collect::<String>()
32        .split('-')
33        .filter(|p| !p.is_empty())
34        .collect::<Vec<_>>()
35        .join("-")
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn slugify_ticket_id() {
44        assert_eq!(slugify("ATH-123"), "ath-123");
45    }
46
47    #[test]
48    fn slugify_spaced_name() {
49        assert_eq!(slugify("auth fix"), "auth-fix");
50    }
51
52    #[test]
53    fn slugify_ticket_with_description() {
54        assert_eq!(slugify("ATH-123 auth fix"), "ath-123-auth-fix");
55    }
56
57    #[test]
58    fn slugify_collapses_consecutive_separators() {
59        assert_eq!(slugify("my  feature!"), "my-feature");
60    }
61
62    #[test]
63    fn slugify_already_clean() {
64        assert_eq!(slugify("my-feature"), "my-feature");
65    }
66
67    #[test]
68    fn slugify_empty_returns_empty() {
69        assert_eq!(slugify(""), "");
70        assert_eq!(slugify("---"), "");
71    }
72}