Skip to main content

oneline_template/template/
template.rs

1use 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
25/// Templates the passed structure. 
26pub 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    /// Creates template using passed template format.
43    pub fn parse(format: &str) -> Result<Template, TemplateBuildError> {
44        let builder = TemplateBuilder::new();
45        return builder.build(format);
46    }
47
48    /// Templates the passed structure.
49    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            // Anyway there is no information inside unstructured::UnstructuredError.
56            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}