From 4c8c1e22c553770162e1cbc94e971a9b41af3c9d Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sun, 30 May 2021 11:33:22 +0800 Subject: [PATCH 1/3] (feat) wip add valuable --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 9aa393be0..a7da8df60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ serde = "1.0.0" serde_json = "1.0.39" walkdir = { version = "2.2.3", optional = true } rhai = { version = "0.20", optional = true, features = ["sync", "serde"] } +valuable = { git = "https://github.com/tokio-rs/valuable.git" } [dev-dependencies] env_logger = "0.8" From d23ffd469c48f8667c5c2d6dd41cde1ced7f84d3 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sat, 3 Jul 2021 22:02:58 +0800 Subject: [PATCH 2/3] (feat) change context api to hold reference for valuable --- src/context.rs | 21 +++++++-------------- src/registry.rs | 12 ++++++------ 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/context.rs b/src/context.rs index 10e15fd90..fb7916c4c 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,7 +1,7 @@ use std::collections::{HashMap, VecDeque}; -use serde::Serialize; use serde_json::value::{to_value, Map, Value as Json}; +use valuable::Valuable; use crate::block::{BlockContext, BlockParamHolder}; use crate::error::RenderError; @@ -15,8 +15,8 @@ pub type Object = HashMap; /// The context wrap data you render on your templates. /// #[derive(Debug, Clone)] -pub struct Context { - data: Json, +pub struct Context<'rc, V: Valuable> { + data: &'rc V, } #[derive(Debug)] @@ -151,21 +151,14 @@ pub(crate) fn merge_json(base: &Json, addition: &HashMap<&str, &Json>) -> Json { Json::Object(base_map) } -impl Context { - /// Create a context with null data - pub fn null() -> Context { - Context { data: Json::Null } - } - +impl<'rc, V: Valuable> Context<'rc, V> { /// Create a context with given data - pub fn wraps(e: T) -> Result { - to_value(e) - .map_err(RenderError::from) - .map(|d| Context { data: d }) + pub fn wraps(e: &'rc V) -> Result, RenderError> { + Ok(Context { data: e }) } /// Navigate the context with relative path and block scopes - pub(crate) fn navigate<'reg, 'rc>( + pub(crate) fn navigate<'reg>( &'rc self, relative_path: &[PathSeg], block_contexts: &VecDeque>, diff --git a/src/registry.rs b/src/registry.rs index e7f5f1cfd..32e88a4f2 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -5,7 +5,7 @@ use std::io::{Error as IoError, Write}; use std::path::Path; use std::sync::Arc; -use serde::Serialize; +use valuable::Valuable; use crate::context::Context; use crate::decorators::{self, DecoratorDef}; @@ -496,12 +496,12 @@ impl<'reg> Registry<'reg> { /// Render a registered template with some data into a string /// /// * `name` is the template name you registered previously - /// * `data` is the data that implements `serde::Serialize` + /// * `data` is the data that implements `valuable::Valuable` /// /// Returns rendered string or a struct with error information pub fn render(&self, name: &str, data: &T) -> Result where - T: Serialize, + T: Valuable, { let mut output = StringOutput::new(); let ctx = Context::wraps(&data)?; @@ -519,7 +519,7 @@ impl<'reg> Registry<'reg> { /// Render a registered template and write some data to the `std::io::Write` pub fn render_to_write(&self, name: &str, data: &T, writer: W) -> Result<(), RenderError> where - T: Serialize, + T: Valuable, W: Write, { let mut output = WriteOutput::new(writer); @@ -530,7 +530,7 @@ impl<'reg> Registry<'reg> { /// Render a template string using current registry without registering it pub fn render_template(&self, template_string: &str, data: &T) -> Result where - T: Serialize, + T: Valuable, { let mut writer = StringWriter::new(); self.render_template_to_write(template_string, data, &mut writer)?; @@ -562,7 +562,7 @@ impl<'reg> Registry<'reg> { writer: W, ) -> Result<(), RenderError> where - T: Serialize, + T: Valuable, W: Write, { let tpl = Template::compile(template_string)?; From fe2fcdd35c31c9751432210fde44019775717a83 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Mon, 5 Jul 2021 00:15:15 +0800 Subject: [PATCH 3/3] (feat) make context value a valuable::Value --- src/json/value.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/json/value.rs b/src/json/value.rs index 863eab0b8..ba2149c6d 100644 --- a/src/json/value.rs +++ b/src/json/value.rs @@ -1,3 +1,5 @@ +use valuable::Value; + use serde::Serialize; use serde_json::value::{to_value, Value as Json}; @@ -8,13 +10,14 @@ pub(crate) static DEFAULT_VALUE: Json = Json::Null; /// * Constant: the JSON value hardcoded into template /// * Context: the JSON value referenced in your provided data context /// * Derived: the owned JSON value computed during rendering process +/// * Missing: the value was not found /// #[derive(Debug)] pub enum ScopedJson<'reg: 'rc, 'rc> { Constant(&'reg Json), Derived(Json), // represents a json reference to context value, its full path - Context(&'rc Json, Vec), + Context(Value<'rc>, Vec), Missing, }