emoji_crafter/renderer/
template_renderer.rs1use crate::document::Emoji;
2use crate::manifest::*;
3use rayon::prelude::*;
4use serde::Serialize;
5use std::path::PathBuf;
6use tinytemplate::TinyTemplate;
7
8#[derive(Serialize)]
9pub struct Renderable {
10 path: PathBuf,
11 newline: String,
12 emojiset: Emojiset,
13 emojis: Vec<RenderableEmoji>,
14 themes: Vec<Theme>,
15 outputs: Vec<Output>,
16}
17
18#[derive(Serialize)]
19pub struct RenderableEmoji {
20 id: String,
21 name: String,
22 is_animation: bool,
23 is_image: bool,
24}
25
26pub trait OnProgress<'a>: Fn(&'a Template) {}
27
28impl<'a, T> OnProgress<'a> for T where T: Fn(&'a Template) {}
29
30pub fn process(project: &Project, emojis: &Vec<Emoji>) -> Renderable {
31 let mut renderable_emoji: Vec<RenderableEmoji> = emojis
32 .par_iter()
33 .filter_map(|emoji| match emoji {
34 Emoji::Animation { id, name, .. } => Some(RenderableEmoji {
35 id: id.clone(),
36 name: name.clone(),
37 is_animation: true,
38 is_image: false,
39 }),
40 Emoji::Image { id, name, .. } => Some(RenderableEmoji {
41 id: id.clone(),
42 name: name.clone(),
43 is_animation: false,
44 is_image: true,
45 }),
46 _ => None,
47 })
48 .collect();
49
50 renderable_emoji.par_sort_by(|a, b| a.name.partial_cmp(&b.name).unwrap());
51
52 Renderable {
53 path: project.path.clone(),
54 newline: "\n".into(),
55 emojiset: project.emojiset.clone(),
56 emojis: renderable_emoji,
57 themes: project.themes.clone(),
58 outputs: project.outputs.clone(),
59 }
60}
61
62pub fn render<'a, F>(context: &Renderable, templates: &'a Vec<Template>, on_progress: F)
63where
64 F: OnProgress<'a> + Sync + Send,
65{
66 templates.par_iter().for_each(|template| {
67 let mut renderer = TinyTemplate::new();
68
69 let input_path = context.path.join(template.input.clone());
70 let output_path = context.path.join(template.output.clone());
71
72 let input = std::fs::read_to_string(&input_path).unwrap();
73
74 renderer.add_template("current", &input).unwrap();
75
76 match renderer.render("current", &context) {
77 Ok(output) => {
78 std::fs::write(&output_path, output).unwrap();
79 }
80 Err(error) => {
81 println!("{}", error);
82
83 std::process::exit(1);
84 }
85 }
86
87 on_progress(template);
88 });
89}