use core::fmt::{Display, Formatter, Result as FmtResult};
use thiserror::Error as ThisError;
use crate::api_verb::ApiVerb;
#[derive(Debug, PartialEq, Eq)]
pub struct MenuItem {
verb: ApiVerb,
description: String,
}
impl MenuItem {
pub fn verb(&self) -> &ApiVerb {
&self.verb
}
pub fn description(&self) -> &String {
&self.description
}
}
#[derive(Debug, ThisError)]
#[non_exhaustive]
pub enum Error {
#[error("failed to parse menu item: {0}")]
ParsingFailed(String),
}
impl TryFrom<&str> for MenuItem {
type Error = Error;
fn try_from(value: &str) -> Result<Self, Self::Error> {
let parts = value.split(':').collect::<Vec<_>>();
let Some((verb, description)) = parts.first().zip(parts.get(2)) else {
return Err(Error::ParsingFailed(format!("invalid menu item: {value}")));
};
Ok(Self {
verb: ApiVerb::try_from(*verb)
.map_err(|err| Error::ParsingFailed(format!("invalid menu item: {err}")))?,
description: (*description).to_owned(),
})
}
}
impl Display for MenuItem {
#[expect(clippy::min_ident_chars, reason = "defined by trait")]
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "{}: {}", self.verb, self.description)
}
}
#[cfg(test)]
#[expect(clippy::unwrap_used, reason = "in tests we panic")]
mod tests {
use super::*;
#[test]
fn test_parsing() {
let item = MenuItem::try_from("ACTIVITY::check activity").unwrap();
let expected = MenuItem {
verb: ApiVerb::Activity,
description: "check activity".to_owned(),
};
assert_eq!(expected, item);
}
#[test]
#[should_panic(expected = "invalid menu item: ACTIVITY:check activity")]
fn test_missing_section() {
let item = MenuItem::try_from("ACTIVITY:check activity").unwrap();
let expected = MenuItem {
verb: ApiVerb::Activity,
description: "check activity".to_owned(),
};
assert_eq!(expected, item);
}
#[test]
#[should_panic(expected = "invalid menu item: ACTIVITY_CHECK:check activity")]
fn test_unknown_verb() {
let item = MenuItem::try_from("ACTIVITY_CHECK:check activity").unwrap();
let expected = MenuItem {
verb: ApiVerb::Activity,
description: "check activity".to_owned(),
};
assert_eq!(expected, item);
}
}