Skip to main content

oo_ide/commands/
id.rs

1use std::{borrow::Cow, fmt, str::FromStr};
2
3use crate::prelude::*;
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub struct CommandId {
7    pub group: Cow<'static, str>,
8    pub name: Cow<'static, str>,
9}
10
11impl CommandId {
12    /// Zero-allocation constructor for static strings known at compile time.
13    pub const fn new_static(group: &'static str, name: &'static str) -> Self {
14        Self {
15            group: Cow::Borrowed(group),
16            name: Cow::Borrowed(name),
17        }
18    }
19}
20
21impl fmt::Display for CommandId {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        write!(f, "{}.{}", self.group, self.name)
24    }
25}
26
27/// Parse `"group.name"` into a `CommandId`.
28/// Panics at the call site if the string is malformed — acceptable for static
29/// registration code that is always developer-controlled.
30impl From<&'static str> for CommandId {
31    fn from(s: &'static str) -> Self {
32        match s.splitn(2, '.').collect::<Vec<_>>().as_slice() {
33            [group, name] => Self::new_static(group, name),
34            _ => panic!("CommandId must be 'group.name', got: {:?}", s),
35        }
36    }
37}
38
39impl From<(&'static str, &'static str)> for CommandId {
40    fn from(value: (&'static str, &'static str)) -> Self {
41        Self::new_static(value.0, value.1)
42    }
43}
44
45impl FromStr for CommandId {
46    type Err = Error;
47
48    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
49        match s.splitn(2, '.').collect::<Vec<_>>().as_slice() {
50            [group, name] => Ok(Self {
51                group: Cow::Owned((*group).to_owned()),
52                name: Cow::Owned((*name).to_owned()),
53            }),
54            _ => Err(anyhow!("CommandId must be 'group.name', got: {:?}", s)),
55        }
56    }
57}