grass/dev/strategy/
alias.rs

1mod local;
2mod mock;
3mod nop;
4mod resolves;
5
6pub use local::LocalAliasStrategy;
7pub use mock::MockAliasStrategy;
8pub use nop::NopAliasStrategy;
9pub use resolves::ResolvesAlias;
10use thiserror::Error;
11
12use crate::{dev::public::api::Category, support_strategy};
13
14/// Error returned by methods of `AliasStrategy`[^strategy].
15///
16/// # Fields
17///
18/// Each variant has at least the following fields:
19///
20/// - `context`: What action was attempted.
21/// - `reason`: What went wrong, often provided by third party crates.
22///
23/// [^strategy]: [crate::dev::strategy::alias::AliasStrategy]
24#[derive(Debug, Error, PartialEq, Eq, PartialOrd, Ord, Hash)]
25pub enum AliasStrategyError {
26    #[error("There is a problem:\nContext: {context}\nReason: {reason}")]
27    UnkownError { context: String, reason: String },
28    #[error("Cannot find category:\nContext: {context}\nReason: {reason}")]
29    CategoryNotFound { context: String, reason: String },
30}
31
32/// Alias for methods of `AliasStrategy`.
33pub type Result<T> = std::result::Result<T, AliasStrategyError>;
34
35/// Describes an alias between
36#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
37pub struct Alias {
38    pub alias: String,
39    pub category: Category,
40}
41
42/// The result from `AliasStrategy::resolve_alias`[^resolve]
43///
44/// [^resolve]: [crate::dev::strategy::alias::AliasStrategy::resolve_alias]
45#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
46pub enum ResolveAliasResult {
47    Alias(Alias),
48    NoAlias(String),
49}
50
51/// Strategy for resolving and listing aliases.
52pub trait AliasStrategy {
53    /// Get a list of all aliases
54    ///
55    /// # Example
56    ///
57    /// ```rust
58    /// # use grass::dev::strategy::alias::{Alias, AliasStrategy, MockAliasStrategy};
59    /// #
60    /// # let strategy = MockAliasStrategy;
61    /// #
62    /// fn test_strategy<T: AliasStrategy>(strategy: &T) {
63    ///     assert_eq!(
64    ///         strategy.list_all_aliases(),
65    ///         Ok(vec![
66    ///             Alias {
67    ///                 alias: "allg".into(),
68    ///                 category: "all_good".into()
69    ///             },
70    ///             Alias {
71    ///                 alias: "change".into(),
72    ///                 category: "with_changes".into()
73    ///             },
74    ///             Alias {
75    ///                 alias: "err".into(),
76    ///                 category: "with_error".into()
77    ///             },
78    ///         ])
79    ///     )
80    /// }
81    ///
82    /// test_strategy(&strategy)
83    /// ```
84    fn list_all_aliases<T>(&self) -> Result<T>
85    where
86        T: FromIterator<Alias>;
87
88    /// Get a list of aliases for a specific category
89    ///
90    /// # Example
91    ///
92    /// ```rust
93    /// # use grass::dev::strategy::alias::{Alias, AliasStrategy, MockAliasStrategy};
94    /// #
95    /// # let strategy = MockAliasStrategy;
96    /// #
97    /// fn test_strategy<T: AliasStrategy>(strategy: &T) {
98    ///     assert_eq!(
99    ///         strategy.list_aliases_for_category("all_good"),
100    ///         Ok(vec![Alias {
101    ///             alias: "allg".into(),
102    ///             category: "all_good".into()
103    ///         }])
104    ///     );
105    /// }
106    ///
107    /// test_strategy(&strategy)
108    /// ```
109    fn list_aliases_for_category<T, U>(&self, category: T) -> Result<U>
110    where
111        T: AsRef<str>,
112        U: FromIterator<Alias>;
113
114    /// Resolves the alias of a type
115    ///
116    /// The input must implement 'ResolvesAlias'[^resolve].
117    ///
118    /// # Example
119    ///
120    /// ```rust
121    /// # use grass::dev::strategy::alias::{
122    /// #     Alias, AliasStrategy, MockAliasStrategy, ResolveAliasResult,
123    /// # };
124    /// #
125    /// # let strategy = MockAliasStrategy;
126    /// #
127    /// fn test_strategy<T: AliasStrategy>(strategy: &T) {
128    ///     assert_eq!(
129    ///         strategy.resolve_alias("allg"),
130    ///         Ok(Box::from("all_good")),
131    ///     );
132    ///
133    ///     assert_eq!(
134    ///         strategy.resolve_alias("mispel"),
135    ///         Ok(Box::from("mispel")),
136    ///     );
137    /// }
138    ///
139    /// test_strategy(&strategy)
140    /// ```
141    ///
142    /// [^resolve]: [crate::dev::strategy::alias::ResolvesAlias]
143    fn resolve_alias<T: ResolvesAlias>(&self, input: T) -> Result<T::Resolved>;
144}
145
146support_strategy!(SupportsAlias, get_alias_strategy, AliasStrategy);
147
148impl<T: Into<String>, U: Into<Category>> From<(T, U)> for Alias {
149    fn from(value: (T, U)) -> Self {
150        let (alias, category) = value;
151
152        let alias = alias.into();
153        let category = category.into();
154
155        Alias { alias, category }
156    }
157}