Skip to main content

sl_types/
search.rs

1//! Search related types
2
3#[cfg(feature = "chumsky")]
4use chumsky::{Parser, prelude::just};
5
6/// Search categories
7#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, strum::EnumIs)]
8#[expect(
9    clippy::module_name_repetitions,
10    reason = "the type is used outside this module"
11)]
12pub enum SearchCategory {
13    /// search in all categories
14    All,
15    /// search for an avatar
16    People,
17    /// search for a parcel
18    Places,
19    /// search for an event
20    Events,
21    /// search for a group
22    Groups,
23    /// search the wiki
24    Wiki,
25    /// search the destination guide
26    Destinations,
27    /// search the classifieds
28    Classifieds,
29}
30
31/// parse a search category
32///
33/// # Errors
34///
35/// returns an error if the string could not be parsed
36#[cfg(feature = "chumsky")]
37#[must_use]
38#[expect(
39    clippy::module_name_repetitions,
40    reason = "the parser is used outside this module"
41)]
42pub fn search_category_parser<'src>()
43-> impl Parser<'src, &'src str, SearchCategory, chumsky::extra::Err<chumsky::error::Rich<'src, char>>>
44{
45    just("all")
46        .to(SearchCategory::All)
47        .or(just("people").to(SearchCategory::People))
48        .or(just("places").to(SearchCategory::Places))
49        .or(just("events").to(SearchCategory::Events))
50        .or(just("groups").to(SearchCategory::Groups))
51        .or(just("wiki").to(SearchCategory::Wiki))
52        .or(just("destinations").to(SearchCategory::Destinations))
53        .or(just("classifieds").to(SearchCategory::Classifieds))
54}
55
56impl std::fmt::Display for SearchCategory {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        match self {
59            Self::All => write!(f, "all"),
60            Self::People => write!(f, "people"),
61            Self::Places => write!(f, "places"),
62            Self::Events => write!(f, "events"),
63            Self::Groups => write!(f, "groups"),
64            Self::Wiki => write!(f, "wiki"),
65            Self::Destinations => write!(f, "destinations"),
66            Self::Classifieds => write!(f, "classifieds"),
67        }
68    }
69}
70
71/// Error deserializing SearchCategory from String
72#[derive(Debug, Clone)]
73#[expect(
74    clippy::module_name_repetitions,
75    reason = "the type is used outside this module"
76)]
77pub struct SearchCategoryParseError {
78    /// the value that could not be parsed
79    value: String,
80}
81
82impl std::fmt::Display for SearchCategoryParseError {
83    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84        write!(f, "Could not parse as SearchCategory: {}", self.value)
85    }
86}
87
88impl std::str::FromStr for SearchCategory {
89    type Err = SearchCategoryParseError;
90
91    fn from_str(s: &str) -> Result<Self, Self::Err> {
92        match s {
93            "all" => Ok(Self::All),
94            "people" => Ok(Self::People),
95            "places" => Ok(Self::Places),
96            "events" => Ok(Self::Events),
97            "groups" => Ok(Self::Groups),
98            "wiki" => Ok(Self::Wiki),
99            "destinations" => Ok(Self::Destinations),
100            "classifieds" => Ok(Self::Classifieds),
101            _ => Err(SearchCategoryParseError {
102                value: s.to_owned(),
103            }),
104        }
105    }
106}