use serde::{Deserialize, Serialize};
use tera::{Context, Tera};
use crate::traits::SrcCode;
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct Generic {
pub(crate) generic: String,
pub(crate) traits: Vec<String>,
}
impl Generic {
pub fn new<S: ToString>(id: S) -> Self {
let mut g = Self::default();
g.generic = id.to_string();
g
}
pub fn add_trait_bounds<S: ToString>(&mut self, traits: Vec<S>) -> &mut Self {
self.traits.extend(traits.iter().map(|t| t.to_string()));
self
}
}
#[derive(Serialize, Deserialize, Default, Clone)]
pub struct Generics {
pub(crate) generics: Vec<Generic>,
}
impl Generics {
pub fn new(generics: Vec<Generic>) -> Self {
Self { generics }
}
pub fn add_generic(&mut self, generic: Generic) -> &mut Self {
self.generics.push(generic);
self
}
pub fn len(&self) -> usize {
self.generics.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl SrcCode for Generics {
fn generate(&self) -> String {
if self.generics.len() > 0 {
let template = r#"<{{ generic_keys | join(sep=", ") }}>
where
{% for generic in generics %}{{ generic.generic }}: {{ generic.traits | join(sep=" + ") }},
{% endfor %}
"#;
let mut context = Context::new();
context.insert(
"generic_keys",
&self
.generics
.iter()
.map(|g| g.generic.clone())
.collect::<Vec<String>>(),
);
context.insert("generics", &self.generics);
Tera::one_off(template, &context, false).unwrap()
} else {
"".to_string()
}
}
}