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