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}