1use serde::Serialize;
6
7use crate::traits::SrcCode;
8use crate::{Function, Generic, Generics, Trait, AssociatedTypeDefinition};
9use tera::{Context, Tera};
10
11#[derive(Serialize, Default, Clone)]
13pub struct Impl {
14 generics: Generics,
15 impl_trait: Option<Trait>,
16 functions: Vec<Function>,
17 obj_name: String,
18 associated_types: Vec<AssociatedTypeDefinition>
19}
20
21impl Impl {
22 pub fn new<S: ToString>(obj_name: S) -> Self {
24 let mut mpl = Self::default();
25 mpl.obj_name = obj_name.to_string();
26 mpl
27 }
28
29 pub fn set_impl_trait(&mut self, impl_trait: Option<Trait>) -> &mut Self {
31 self.impl_trait = impl_trait;
32 self
33 }
34
35 pub fn add_function(&mut self, func: Function) -> &mut Self {
37 self.functions.push(func);
38 self
39 }
40
41 pub fn add_generic(&mut self, generic: Generic) -> &mut Self {
43 self.generics.add_generic(generic);
44 self
45 }
46
47 pub fn add_associated_type(&mut self, associated_type: AssociatedTypeDefinition) -> &mut Self {
49 self.associated_types.push(associated_type);
50 self
51 }
52}
53
54impl SrcCode for Impl {
55 fn generate(&self) -> String {
56 let template = r#"
57 impl{% if has_generics %}<{{ generic_keys | join(sep=", ") }}>{% endif %} {% if has_trait %}{{ trait_name }} for {% endif %}{{ self.obj_name }}{% if has_generics %}<{{ generic_keys | join(sep=", ") }}>{% endif %}
58 {% if has_generics %}
59 where
60 {% for generic in generics %}{{ generic.generic }}: {{ generic.traits | join(sep=" + ") }},
61 {% endfor %}
62 {% endif %}
63 {
64 {% for associated_type in associated_types %}{{ associated_type }}{% endfor %}
65 {% for function in functions %}
66 {{ function }}
67 {% endfor %}
68 }
69 "#;
70 let mut context = Context::new();
71 context.insert("self", &self);
72 context.insert("has_trait", &self.impl_trait.is_some());
73 context.insert(
74 "trait_name",
75 &self
76 .impl_trait
77 .as_ref()
78 .map(|t| t.name.clone())
79 .unwrap_or("".to_string()),
80 );
81 context.insert("has_generics", &!self.generics.is_empty());
82 context.insert("generics", &self.generics.generics);
83 context.insert(
84 "generic_keys",
85 &self
86 .generics
87 .generics
88 .iter()
89 .map(|g| g.generic.clone())
90 .collect::<Vec<String>>(),
91 );
92 context.insert(
93 "functions",
94 &self
95 .functions
96 .iter()
97 .map(|f| f.generate())
98 .collect::<Vec<String>>(),
99 );
100 context.insert(
101 "associated_types",
102 &self
103 .associated_types
104 .iter()
105 .map(|a| a.generate())
106 .collect::<Vec<String>>(),
107 );
108 Tera::one_off(template, &context, false).unwrap()
109 }
110}