oneline_template/template/
template.rs1use crate::function_executor::Value;
2use crate::template::syntax::function_call_token::FunctionCallToken;
3use crate::template::syntax::token::Token;
4use crate::template::syntax::syntax::Syntax;
5use crate::template::syntax::field_read_token::FieldReadToken;
6use crate::template::syntax::field::Field;
7use crate::function_executor::FunctionExecutor;
8use crate::template::TemplateBuilder;
9use crate::template::template_build_error::TemplateBuildError;
10use std::collections::HashMap;
11use std::fmt;
12use std::any::type_name;
13use unstructured::Document;
14use serde::Serialize;
15mod convert_document;
16use self::convert_document::convert_document;
17mod convert_function_argument;
18use self::convert_function_argument::convert_function_argument;
19mod convert_value_to_string;
20use self::convert_value_to_string::convert_value_to_string;
21mod template_error;
22pub use self::template_error::TemplateError;
23
24
25pub struct Template {
27 syntax: Syntax,
28 functions: HashMap<String, Box<dyn FunctionExecutor>>,
29}
30
31impl Template {
32 pub (crate) fn new(
33 syntax: Syntax,
34 functions: HashMap<String, Box<dyn FunctionExecutor>>,
35 ) -> Template {
36 return Template {
37 syntax,
38 functions,
39 }
40 }
41
42 pub fn parse(format: &str) -> Result<Template, TemplateBuildError> {
44 let builder = TemplateBuilder::new();
45 return builder.build(format);
46 }
47
48 pub fn serialize<T>(&self, value: &T) -> Result<String, TemplateError>
50 where
51 T: Serialize,
52 {
53 let mut result = String::new();
54 let document: Document = Document::new(value).map_err(|_| {
55 return TemplateError::SerializationError;
57 })?;
58 for token in self.syntax.iter_tokens() {
59 match token {
60 Token::Text(ref text) => {
61 result += text;
62 },
63 Token::Template(ref template) => {
64 result += self.read_field(&document, template.get_field_read_token())?.as_str();
65 },
66 }
67 }
68 return Ok(result);
69 }
70
71 fn read_field(&self, mut document: &Document, template: &FieldReadToken) -> Result<String, TemplateError> {
72 for field in template.get_path().get_fields().iter() {
73 match field {
74 Field::Field(field_name) => {
75 document = &document[field_name.as_str()];
76 },
77 Field::Index(index) => {
78 document = &document[index];
79 },
80 }
81 }
82 let mut value = convert_document(document, template.get_path())?;
83 for function_call in template.get_function_calls().iter() {
84 value = self.execute_function(value, function_call)?;
85 }
86 let value = convert_value_to_string(value)?;
87 return Ok(value);
88 }
89
90 fn execute_function(&self, input: Value, function_call: &FunctionCallToken) -> Result<Value, TemplateError> {
91 let function_name = function_call.get_function_name().as_string_ref();
92 let function_executor = self
93 .functions
94 .get(function_name)
95 .ok_or_else(|| {
96 return TemplateError::FunctionNotFound(function_name.to_string());
97 })?;
98 let arguments: Vec<_> = function_call
99 .get_arguments()
100 .iter()
101 .map(convert_function_argument)
102 .collect();
103 let value = function_executor.call(input, &arguments)?;
104 return Ok(value);
105 }
106}
107
108impl fmt::Debug for Template {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 let mut functions = HashMap::new();
111 for function_name in self.functions.keys() {
112 let _ = functions.insert(function_name, ());
113 }
114 f.debug_struct(type_name::<Self>())
115 .field("syntax", &self.syntax)
116 .field("functions", &functions)
117 .finish()
118 }
119}