pop_common/templates/
mod.rsuse strum::{EnumMessage, EnumProperty, VariantArray};
pub use thiserror::Error;
pub mod extractor;
#[derive(Error, Debug)]
pub enum Error {
#[error("The `Repository` property is missing from the template variant")]
RepositoryMissing,
#[error("The `TypeMissing` property is missing from the template variant")]
TypeMissing,
}
pub trait Template:
Clone + Default + EnumMessage + EnumProperty + Eq + PartialEq + VariantArray
{
const PROPERTY: &'static str = "Type";
fn name(&self) -> &str {
self.get_message().unwrap_or_default()
}
fn description(&self) -> &str {
self.get_detailed_message().unwrap_or_default()
}
fn repository_url(&self) -> Result<&str, Error> {
self.get_str("Repository").ok_or(Error::RepositoryMissing)
}
fn templates() -> &'static [Self] {
Self::VARIANTS
}
fn template_type(&self) -> Result<&str, Error> {
self.get_str(Self::PROPERTY).ok_or(Error::TypeMissing)
}
}
pub trait Type<T: Template>: Clone + Default + EnumMessage + Eq + PartialEq + VariantArray {
fn types() -> &'static [Self] {
Self::VARIANTS
}
fn name(&self) -> &str {
self.get_message().unwrap_or_default()
}
fn default_template(&self) -> Option<T> {
None
}
fn description(&self) -> &str {
self.get_detailed_message().unwrap_or_default()
}
fn templates(&self) -> Vec<&T> {
T::VARIANTS
.iter()
.filter(|t| t.get_str(T::PROPERTY) == Some(self.name()))
.collect()
}
fn provides(&self, template: &T) -> bool {
template.get_str(T::PROPERTY) == Some(self.name())
}
}
#[macro_export]
macro_rules! enum_variants {
($e: ty) => {{
PossibleValuesParser::new(
<$e>::VARIANTS
.iter()
.map(|p| PossibleValue::new(p.as_ref()))
.collect::<Vec<_>>(),
)
.try_map(|s| <$e>::from_str(&s).map_err(|e| format!("could not convert from {s} to type")))
}};
}