use serde::Serialize;
use tera::{Context, Tera};
use crate::*;
#[derive(Default, Serialize, Clone)]
pub struct Module {
name: String,
is_pub: bool,
traits: Vec<Trait>,
functions: Vec<Function>,
structs: Vec<Struct>,
impls: Vec<Impl>,
enums: Vec<Enum>,
docs: Vec<String>,
sub_modules: Vec<Module>,
inner_annotations: Vec<String>,
outer_annotations: Vec<String>,
use_stmts: Vec<String>,
}
impl Module {
pub fn new<S: ToString>(name: S) -> Self {
let mut m = Module::default();
m.name = name.to_string();
m
}
pub fn set_is_pub(&mut self, is_pub: bool) -> &mut Self {
self.is_pub = is_pub;
self
}
pub fn add_submodule(&mut self, module: Module) -> &mut Self {
self.sub_modules.push(module);
self
}
pub fn add_function(&mut self, func: Function) -> &mut Self {
self.functions.push(func);
self
}
pub fn add_trait(&mut self, tr8t: Trait) -> &mut Self {
self.traits.push(tr8t);
self
}
pub fn add_struct(&mut self, stct: Struct) -> &mut Self {
self.structs.push(stct);
self
}
pub fn add_impl(&mut self, iml: Impl) -> &mut Self {
self.impls.push(iml);
self
}
pub fn add_use_statement<S: ToString>(&mut self, stmt: S) -> &mut Self {
self.use_stmts.push(stmt.to_string());
self
}
pub fn add_outer_annotation<S: ToString>(&mut self, ann: S) -> &mut Self {
self.outer_annotations.push(ann.to_string());
self
}
pub fn add_inner_annotation<S: ToString>(&mut self, ann: S) -> &mut Self {
self.inner_annotations.push(ann.to_string());
self
}
pub fn add_doc<S: ToString>(&mut self, doc: S) -> &mut Self {
self.docs.push(doc.to_string());
self
}
pub fn add_enum(&mut self, enumm: Enum) -> &mut Self {
self.enums.push(enumm);
self
}
}
impl SrcCode for Module {
fn generate(&self) -> String {
let template = r#"
{% for annotation in self.outer_annotations %}{{ annotation }}{% endfor %}
{% if self.is_pub %}pub {% endif %}mod {{ self.name }}
{
{% for stmt in self.use_stmts %}{{ stmt }}{% endfor %}
{% for annotation in self.inner_annotations %}{{ annotation }}{% endfor %}
{% for doc in self.docs %}{{ doc }}{% endfor %}
{% for obj in objs %}{{ obj }}{% endfor %}
{% for sub_mod in submodules %}{{ sub_mod }}{% endfor %}
}
"#;
let mut ctx = Context::new();
ctx.insert("self", &self);
let mut objs: Vec<String> = vec![];
&self.traits.iter().for_each(|v| objs.push(v.generate()));
&self.functions.iter().for_each(|v| objs.push(v.generate()));
&self.structs.iter().for_each(|v| objs.push(v.generate()));
&self.impls.iter().for_each(|v| objs.push(v.generate()));
&self.enums.iter().for_each(|v| objs.push(v.generate()));
ctx.insert("objs", &objs);
ctx.insert(
"submodules",
&self
.sub_modules
.iter()
.map(|m| m.generate())
.collect::<Vec<String>>(),
);
Tera::one_off(template, &ctx, false).unwrap()
}
}