json_template/functions/
mod.rs1use std::{collections::HashMap, rc::Rc};
4
5use serde_json::Value;
6
7use crate::{Context, Deserializer, Placeholder, JSON};
8
9
10#[derive(Clone)]
12pub struct Functions {
13 registry: HashMap<String, Rc<dyn Fn(&Deserializer, &Context, &Placeholder) -> serde_json::Result<Value>>>
14}
15
16fn string(deserializer: &Deserializer, context: &Context, placeholder: &Placeholder) -> serde_json::Result<Value> {
18 context.find(deserializer, placeholder).map(|value| Value::String(value.to_string()))
19}
20
21fn file(deserializer: &Deserializer, context: &Context, placeholder: &Placeholder) -> serde_json::Result<Value> {
23 context
24 .directory()
25 .as_ref()
26 .map(|directory| directory.join(placeholder.path().str()))
27 .ok_or_else(|| serde::de::Error::custom("No directory set."))
28 .and_then(|path| deserializer.deserialize_with_context::<Value>(path, context))
29}
30
31fn compose(deserializer: &Deserializer, context: &Context, placeholder: &Placeholder) -> serde_json::Result<Value> {
33 let path = placeholder.path();
34 let parts = path.str().split(',').collect::<Vec<_>>();
35 let mut value = Value::Object(Default::default());
36 for part in parts {
37 let new_value = deserializer.resolve_string(part, context)?;
38 value.add_recursive(new_value);
39 }
40 Ok(value)
41}
42
43impl Default for Functions {
44 fn default() -> Self {
45 let registry = Default::default();
46 let mut functions = Functions { registry };
47 functions.register("string", string);
48 functions.register("file", file);
49 functions.register("compose", compose);
50 functions
51 }
52}
53
54impl Functions {
55 pub fn register(&mut self, name: impl AsRef<str>, function: impl Fn(&Deserializer, &Context, &Placeholder) -> serde_json::Result<Value> + 'static) {
57 self.registry.insert(name.as_ref().to_string(), Rc::new(function));
58 }
59
60 pub fn get(&self, name: impl AsRef<str>) -> Option<Rc<dyn Fn(&Deserializer, &Context, &Placeholder) -> serde_json::Result<Value>>> {
62 self.registry.get(name.as_ref()).cloned()
63 }
64}