pop_common/templates/
mod.rs1use strum::{EnumMessage, EnumProperty, VariantArray};
4pub use thiserror::Error;
5
6pub mod extractor;
8pub mod frontend;
10
11#[derive(Error, Debug)]
13pub enum Error {
14 #[error("The `Repository` property is missing from the template variant")]
16 RepositoryMissing,
17 #[error("The `TypeMissing` property is missing from the template variant")]
19 TypeMissing,
20}
21
22pub trait Template:
24 Clone + Default + EnumMessage + EnumProperty + Eq + PartialEq + VariantArray
25{
26 const PROPERTY: &'static str = "Type";
28
29 fn name(&self) -> &str {
31 self.get_message().unwrap_or_default()
32 }
33
34 fn description(&self) -> &str {
36 self.get_detailed_message().unwrap_or_default()
37 }
38
39 fn repository_url(&self) -> Result<&str, Error> {
41 self.get_str("Repository").ok_or(Error::RepositoryMissing)
42 }
43
44 fn templates() -> &'static [Self] {
46 Self::VARIANTS
47 }
48
49 fn template_type(&self) -> Result<&str, Error> {
51 self.get_str(Self::PROPERTY).ok_or(Error::TypeMissing)
52 }
53
54 fn is_deprecated(&self) -> bool {
56 self.get_str("IsDeprecated") == Some("true")
57 }
58
59 fn deprecated_message(&self) -> &str {
61 self.get_str("DeprecatedMessage").unwrap_or_default()
62 }
63}
64
65pub trait Type<T: Template>: Clone + Default + EnumMessage + Eq + PartialEq + VariantArray {
70 fn types() -> &'static [Self] {
72 Self::VARIANTS
73 }
74
75 fn name(&self) -> &str {
77 self.get_message().unwrap_or_default()
78 }
79
80 fn default_template(&self) -> Option<T> {
82 None
83 }
84
85 fn description(&self) -> &str {
87 self.get_detailed_message().unwrap_or_default()
88 }
89
90 fn templates(&self) -> Vec<&T> {
92 T::VARIANTS
93 .iter()
94 .filter(|t| t.get_str(T::PROPERTY) == Some(self.name()) && !t.is_deprecated())
95 .collect()
96 }
97
98 fn provides(&self, template: &T) -> bool {
100 template.get_str(T::PROPERTY) == Some(self.name())
102 }
103}
104
105#[macro_export]
107macro_rules! enum_variants {
108 ($e: ty) => {{
109 PossibleValuesParser::new(
110 <$e>::VARIANTS
111 .iter()
112 .map(|p| PossibleValue::new(p.as_ref()))
113 .collect::<Vec<_>>(),
114 )
115 .try_map(|s| <$e>::from_str(&s).map_err(|e| format!("could not convert from {s} to type")))
116 }};
117}
118
119#[macro_export]
121macro_rules! enum_variants_without_deprecated {
122 ($e:ty) => {{
123 <$e>::VARIANTS
124 .iter()
125 .filter(|variant| !variant.is_deprecated()) .map(|v| v.as_ref())
127 .collect::<Vec<_>>()
128 .join(", ")
129 }};
130}