Re-enable the ContextElement implementation for serde_json

This commit is contained in:
Tom Alexander 2020-06-07 00:17:55 -04:00
parent 422479bcf2
commit 669a698575
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

View File

@ -53,13 +53,12 @@ fn main() {
compiled_templates.iter().for_each(|(name, template)| { compiled_templates.iter().for_each(|(name, template)| {
dust_renderer.load_source(template, name.to_owned()); dust_renderer.load_source(template, name.to_owned());
}); });
// let breadcrumbs = vec![&context as &dyn IntoContextElement]; println!(
// println!( "{}",
// "{}", dust_renderer
// dust_renderer .render(main_template_name, Some(&context))
// .render(main_template_name, &breadcrumbs) .expect("Failed to render")
// .expect("Failed to render") );
// );
} }
fn template_from_file<'a>( fn template_from_file<'a>(
@ -171,288 +170,288 @@ fn encode_uri_component(inp: &str) -> String {
output output
} }
// fn apply_filter( fn apply_filter(
// json_value: &serde_json::Value, json_value: &serde_json::Value,
// filter: &Filter, filter: &Filter,
// ) -> Result<serde_json::Value, RenderError> { ) -> Result<serde_json::Value, RenderError> {
// match (json_value, filter) { match (json_value, filter) {
// // Html escape filter // Html escape filter
// (serde_json::Value::String(string), Filter::HtmlEncode) => { (serde_json::Value::String(string), Filter::HtmlEncode) => {
// Ok(serde_json::Value::String(html_escape(string))) Ok(serde_json::Value::String(html_escape(string)))
// } }
// (_, Filter::HtmlEncode) => Ok(serde_json::Value::String(html_escape( (_, Filter::HtmlEncode) => Ok(serde_json::Value::String(html_escape(
// &json_value.render(&Vec::new())?, &json_value.render(&Vec::new())?,
// ))), ))),
// // Disable html escape filter // Disable html escape filter
// (_, Filter::DisableHtmlEncode) => panic!("The |s filter is automatically removed by the renderer since it is a no-op during rendering."), (_, Filter::DisableHtmlEncode) => panic!("The |s filter is automatically removed by the renderer since it is a no-op during rendering."),
// // Parse JSON filter // Parse JSON filter
// (serde_json::Value::String(string), Filter::JsonParse) => { (serde_json::Value::String(string), Filter::JsonParse) => {
// serde_json::from_str(&string).or(Err(RenderError::InvalidJson(string.to_owned()))) serde_json::from_str(&string).or(Err(RenderError::InvalidJson(string.to_owned())))
// } }
// (_, Filter::JsonParse) => { (_, Filter::JsonParse) => {
// let rendered_value = json_value.render(&Vec::new())?; let rendered_value = json_value.render(&Vec::new())?;
// serde_json::from_str(&rendered_value).or(Err(RenderError::InvalidJson(rendered_value))) serde_json::from_str(&rendered_value).or(Err(RenderError::InvalidJson(rendered_value)))
// } }
// // Json Stringify filter // Json Stringify filter
// (_, Filter::JsonStringify) => { (_, Filter::JsonStringify) => {
// Ok(serde_json::Value::String(json_value.to_string())) Ok(serde_json::Value::String(json_value.to_string()))
// } }
// // Javascript escape filter // Javascript escape filter
// (serde_json::Value::String(string), Filter::JavascriptStringEncode) => { (serde_json::Value::String(string), Filter::JavascriptStringEncode) => {
// Ok(serde_json::Value::String(javascript_escape(string))) Ok(serde_json::Value::String(javascript_escape(string)))
// } }
// (serde_json::Value::Bool(boolean), Filter::JavascriptStringEncode) => { (serde_json::Value::Bool(boolean), Filter::JavascriptStringEncode) => {
// Ok(serde_json::Value::Bool(*boolean)) Ok(serde_json::Value::Bool(*boolean))
// } }
// (serde_json::Value::Number(number), Filter::JavascriptStringEncode) => { (serde_json::Value::Number(number), Filter::JavascriptStringEncode) => {
// Ok(serde_json::Value::Number(number.clone())) Ok(serde_json::Value::Number(number.clone()))
// } }
// (serde_json::Value::Array(arr), Filter::JavascriptStringEncode) => { (serde_json::Value::Array(arr), Filter::JavascriptStringEncode) => {
// Ok(serde_json::Value::Array(arr.clone())) Ok(serde_json::Value::Array(arr.clone()))
// } }
// (serde_json::Value::Object(obj), Filter::JavascriptStringEncode) => { (serde_json::Value::Object(obj), Filter::JavascriptStringEncode) => {
// Ok(serde_json::Value::Object(obj.clone())) Ok(serde_json::Value::Object(obj.clone()))
// } }
// (_, Filter::JavascriptStringEncode) => Ok(serde_json::Value::String(javascript_escape( (_, Filter::JavascriptStringEncode) => Ok(serde_json::Value::String(javascript_escape(
// &json_value.render(&Vec::new())?, &json_value.render(&Vec::new())?,
// ))), ))),
// // EncodeURI filter // EncodeURI filter
// (serde_json::Value::String(string), Filter::EncodeUri) => { (serde_json::Value::String(string), Filter::EncodeUri) => {
// Ok(serde_json::Value::String(encode_uri(string))) Ok(serde_json::Value::String(encode_uri(string)))
// } }
// (_, Filter::EncodeUri) => Ok(serde_json::Value::String(encode_uri( (_, Filter::EncodeUri) => Ok(serde_json::Value::String(encode_uri(
// &json_value.render(&Vec::new())?, &json_value.render(&Vec::new())?,
// ))), ))),
// // EncodeURIComponent filter // EncodeURIComponent filter
// (serde_json::Value::String(string), Filter::EncodeUriComponent) => { (serde_json::Value::String(string), Filter::EncodeUriComponent) => {
// Ok(serde_json::Value::String(encode_uri_component(string))) Ok(serde_json::Value::String(encode_uri_component(string)))
// } }
// (_, Filter::EncodeUriComponent) => Ok(serde_json::Value::String(encode_uri_component( (_, Filter::EncodeUriComponent) => Ok(serde_json::Value::String(encode_uri_component(
// &json_value.render(&Vec::new())?, &json_value.render(&Vec::new())?,
// ))), ))),
// } }
// } }
// fn apply_filters( fn apply_filters(
// json_value: &serde_json::Value, json_value: &serde_json::Value,
// filters: &[Filter], filters: &[Filter],
// ) -> Result<serde_json::Value, RenderError> { ) -> Result<serde_json::Value, RenderError> {
// let mut final_value: serde_json::Value = apply_filter(json_value, &filters[0])?; let mut final_value: serde_json::Value = apply_filter(json_value, &filters[0])?;
// for filter in &filters[1..] { for filter in &filters[1..] {
// final_value = apply_filter(&final_value, filter)?; final_value = apply_filter(&final_value, filter)?;
// } }
// Ok(final_value) Ok(final_value)
// } }
// impl ContextElement for serde_json::Value {} impl ContextElement for serde_json::Value {}
// impl Truthiness for serde_json::Value { impl Truthiness for serde_json::Value {
// fn is_truthy(&self) -> bool { fn is_truthy(&self) -> bool {
// match self { match self {
// serde_json::Value::Null => false, serde_json::Value::Null => false,
// serde_json::Value::Bool(boolean) => *boolean, serde_json::Value::Bool(boolean) => *boolean,
// serde_json::Value::Number(_num) => true, serde_json::Value::Number(_num) => true,
// serde_json::Value::String(string_value) => !string_value.is_empty(), serde_json::Value::String(string_value) => !string_value.is_empty(),
// serde_json::Value::Array(array_value) => !array_value.is_empty(), serde_json::Value::Array(array_value) => !array_value.is_empty(),
// serde_json::Value::Object(_obj) => true, serde_json::Value::Object(_obj) => true,
// } }
// } }
// } }
// impl Renderable for serde_json::Value { impl Renderable for serde_json::Value {
// fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> { fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
// let after_apply = if _filters.is_empty() { let after_apply = if _filters.is_empty() {
// None None
// } else { } else {
// Some(apply_filters(self, _filters)?) Some(apply_filters(self, _filters)?)
// }; };
// match after_apply.as_ref().unwrap_or(self) { match after_apply.as_ref().unwrap_or(self) {
// serde_json::Value::Null => Ok("".to_owned()), serde_json::Value::Null => Ok("".to_owned()),
// serde_json::Value::Bool(boolean) => Ok(boolean.to_string()), serde_json::Value::Bool(boolean) => Ok(boolean.to_string()),
// serde_json::Value::Number(num) => Ok(num.to_string()), serde_json::Value::Number(num) => Ok(num.to_string()),
// serde_json::Value::String(string) => Ok(string.to_string()), serde_json::Value::String(string) => Ok(string.to_string()),
// serde_json::Value::Array(arr) => { serde_json::Value::Array(arr) => {
// // TODO: Handle the filters instead of passing a Vec::new() // TODO: Handle the filters instead of passing a Vec::new()
// let rendered: Result<Vec<String>, RenderError> = let rendered: Result<Vec<String>, RenderError> =
// arr.iter().map(|val| val.render(&Vec::new())).collect(); arr.iter().map(|val| val.render(&Vec::new())).collect();
// let rendered_slice: &[String] = &rendered?; let rendered_slice: &[String] = &rendered?;
// Ok(rendered_slice.join(",")) Ok(rendered_slice.join(","))
// } }
// serde_json::Value::Object(_obj) => Ok("[object Object]".to_owned()), serde_json::Value::Object(_obj) => Ok("[object Object]".to_owned()),
// } }
// } }
// } }
// impl Walkable for serde_json::Value { impl Walkable for serde_json::Value {
// fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> { fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> {
// match self { match self {
// serde_json::Value::Null => Err(WalkError::CantWalk), serde_json::Value::Null => Err(WalkError::CantWalk),
// serde_json::Value::Bool(_boolean) => Err(WalkError::CantWalk), serde_json::Value::Bool(_boolean) => Err(WalkError::CantWalk),
// serde_json::Value::Number(_num) => Err(WalkError::CantWalk), serde_json::Value::Number(_num) => Err(WalkError::CantWalk),
// serde_json::Value::String(_string) => Err(WalkError::CantWalk), serde_json::Value::String(_string) => Err(WalkError::CantWalk),
// serde_json::Value::Array(_arr) => Err(WalkError::CantWalk), serde_json::Value::Array(_arr) => Err(WalkError::CantWalk),
// serde_json::Value::Object(obj) => obj serde_json::Value::Object(obj) => obj
// .get(segment) .get(segment)
// .map(|val| val as _) .map(|val| val as _)
// .ok_or(WalkError::CantWalk), .ok_or(WalkError::CantWalk),
// } }
// } }
// } }
// impl Loopable for serde_json::Value { impl Loopable for serde_json::Value {
// fn get_loop_elements(&self) -> Vec<&dyn ContextElement> { fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
// match self { match self {
// serde_json::Value::Array(array_value) => array_value.iter().map(|x| x as _).collect(), serde_json::Value::Array(array_value) => array_value.iter().map(|x| x as _).collect(),
// _ => Vec::new(), _ => Vec::new(),
// } }
// } }
// } }
// impl CompareContextElement for serde_json::Value { impl CompareContextElement for serde_json::Value {
// fn equals(&self, other: &dyn ContextElement) -> bool { fn equals(&self, other: &dyn ContextElement) -> bool {
// // println!("equals json {:?} | {:?}", self, other); // println!("equals json {:?} | {:?}", self, other);
// // Handle other serde_json::Value // Handle other serde_json::Value
// match other.to_any().downcast_ref::<Self>() { match other.to_any().downcast_ref::<Self>() {
// None => (), None => (),
// Some(other_json_value) => match (self, other_json_value) { Some(other_json_value) => match (self, other_json_value) {
// // Non-scalar values not caught in the renderer by the // Non-scalar values not caught in the renderer by the
// // identical-path shortcut are always not equal. // identical-path shortcut are always not equal.
// (serde_json::Value::Array(_), _) (serde_json::Value::Array(_), _)
// | (_, serde_json::Value::Array(_)) | (_, serde_json::Value::Array(_))
// | (serde_json::Value::Object(_), _) | (serde_json::Value::Object(_), _)
// | (_, serde_json::Value::Object(_)) => return false, | (_, serde_json::Value::Object(_)) => return false,
// _ => return self == other_json_value, _ => return self == other_json_value,
// }, },
// } }
// // Handle literals // Handle literals
// match other.to_any().downcast_ref::<OwnedLiteral>() { match other.to_any().downcast_ref::<OwnedLiteral>() {
// None => (), None => (),
// Some(OwnedLiteral::LString(other_string)) => { Some(OwnedLiteral::LString(other_string)) => {
// return self.as_str().map_or(false, |s| s == other_string) return self.as_str().map_or(false, |s| s == other_string)
// } }
// Some(OwnedLiteral::LPositiveInteger(other_num)) => { Some(OwnedLiteral::LPositiveInteger(other_num)) => {
// return self.as_u64().map_or(false, |n| n == *other_num) return self.as_u64().map_or(false, |n| n == *other_num)
// } }
// } }
// false false
// } }
// fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> { fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> {
// // println!("partial_compare json {:?} | {:?}", self, other); // println!("partial_compare json {:?} | {:?}", self, other);
// // Handle type coerced objects // Handle type coerced objects
// // When doing a greater than or less than comparison, // When doing a greater than or less than comparison,
// // javascript coerces objects into "[object Object]". // javascript coerces objects into "[object Object]".
// if let serde_json::Value::Object(_) = self { if let serde_json::Value::Object(_) = self {
// return OwnedLiteral::LString(self.render(&Vec::new()).unwrap_or("".to_owned())) return OwnedLiteral::LString(self.render(&Vec::new()).unwrap_or("".to_owned()))
// .partial_compare(other); .partial_compare(other);
// } }
// // When doing a greater than or less than comparison // When doing a greater than or less than comparison
// // javascript turns arrays into strings. // javascript turns arrays into strings.
// if let serde_json::Value::Array(_) = self { if let serde_json::Value::Array(_) = self {
// return OwnedLiteral::LString(self.render(&Vec::new()).unwrap_or("".to_owned())) return OwnedLiteral::LString(self.render(&Vec::new()).unwrap_or("".to_owned()))
// .partial_compare(other); .partial_compare(other);
// } }
// // Handle other serde_json::Value // Handle other serde_json::Value
// match other.to_any().downcast_ref::<Self>() { match other.to_any().downcast_ref::<Self>() {
// None => (), None => (),
// Some(other_json_value) => { Some(other_json_value) => {
// return match (self, other_json_value) { return match (self, other_json_value) {
// ( (
// serde_json::Value::Bool(self_boolean), serde_json::Value::Bool(self_boolean),
// serde_json::Value::Bool(other_boolean), serde_json::Value::Bool(other_boolean),
// ) => self_boolean.partial_cmp(other_boolean), ) => self_boolean.partial_cmp(other_boolean),
// ( (
// serde_json::Value::Number(self_number), serde_json::Value::Number(self_number),
// serde_json::Value::Number(other_number), serde_json::Value::Number(other_number),
// ) => return compare_json_numbers(self_number, other_number), ) => return compare_json_numbers(self_number, other_number),
// ( (
// serde_json::Value::String(self_string), serde_json::Value::String(self_string),
// serde_json::Value::Number(other_number), serde_json::Value::Number(other_number),
// ) => return compare_json_numbers(self_string, other_number), ) => return compare_json_numbers(self_string, other_number),
// ( (
// serde_json::Value::Number(self_number), serde_json::Value::Number(self_number),
// serde_json::Value::String(other_string), serde_json::Value::String(other_string),
// ) => return compare_json_numbers(self_number, other_string), ) => return compare_json_numbers(self_number, other_string),
// ( (
// serde_json::Value::String(self_string), serde_json::Value::String(self_string),
// serde_json::Value::String(other_string), serde_json::Value::String(other_string),
// ) => self_string.partial_cmp(other_string), ) => self_string.partial_cmp(other_string),
// ( (
// serde_json::Value::Array(self_array), serde_json::Value::Array(self_array),
// serde_json::Value::Array(other_array), serde_json::Value::Array(other_array),
// ) => { ) => {
// return self return self
// .render(&Vec::new()) .render(&Vec::new())
// .unwrap_or("".to_owned()) .unwrap_or("".to_owned())
// .partial_cmp( .partial_cmp(
// &other_json_value &other_json_value
// .render(&Vec::new()) .render(&Vec::new())
// .unwrap_or("".to_owned()), .unwrap_or("".to_owned()),
// ) )
// } }
// _ => None, _ => None,
// }; };
// } }
// } }
// // Handle literals // Handle literals
// match other.to_any().downcast_ref::<OwnedLiteral>() { match other.to_any().downcast_ref::<OwnedLiteral>() {
// None => (), None => (),
// Some(other_literal) => match (self, other_literal) { Some(other_literal) => match (self, other_literal) {
// (serde_json::Value::String(self_string), OwnedLiteral::LString(other_string)) => { (serde_json::Value::String(self_string), OwnedLiteral::LString(other_string)) => {
// return self_string.partial_cmp(other_string) return self_string.partial_cmp(other_string)
// } }
// ( (
// serde_json::Value::String(self_string), serde_json::Value::String(self_string),
// OwnedLiteral::LPositiveInteger(other_num), OwnedLiteral::LPositiveInteger(other_num),
// ) => return compare_json_numbers(self_string, other_literal), ) => return compare_json_numbers(self_string, other_literal),
// (serde_json::Value::Number(self_num), OwnedLiteral::LString(other_string)) => { (serde_json::Value::Number(self_num), OwnedLiteral::LString(other_string)) => {
// return compare_json_numbers(self_num, other_string) return compare_json_numbers(self_num, other_string)
// } }
// ( (
// serde_json::Value::Number(self_num), serde_json::Value::Number(self_num),
// OwnedLiteral::LPositiveInteger(other_num), OwnedLiteral::LPositiveInteger(other_num),
// ) => return compare_json_numbers(self_num, other_literal), ) => return compare_json_numbers(self_num, other_literal),
// (serde_json::Value::Array(_), _) => { (serde_json::Value::Array(_), _) => {
// // TODO // TODO
// todo!() todo!()
// } }
// (serde_json::Value::Object(_), _) => { (serde_json::Value::Object(_), _) => {
// // TODO // TODO
// todo!() todo!()
// } }
// (serde_json::Value::Bool(_), _) => { (serde_json::Value::Bool(_), _) => {
// // TODO // TODO
// todo!() todo!()
// } }
// (serde_json::Value::Null, _) => { (serde_json::Value::Null, _) => {
// // TODO // TODO
// todo!() todo!()
// } }
// }, },
// } }
// None None
// } }
// } }
// /// Create a new vec by of references to the serde_json::Values as /// Create a new vec by of references to the serde_json::Values as
// /// ContextElement trait objects so we can use its implementation of /// ContextElement trait objects so we can use its implementation of
// /// PartialOrd. /// PartialOrd.
// /// ///
// /// You cannot implement a trait you do not define for a type you do /// You cannot implement a trait you do not define for a type you do
// /// not define, so I cannot implement PartialOrd for /// not define, so I cannot implement PartialOrd for
// /// serde_json::value. Instead, I just re-use the PartialOrd /// serde_json::value. Instead, I just re-use the PartialOrd
// /// implementation for ContextElement which unfortunately has extra /// implementation for ContextElement which unfortunately has extra
// /// overhead of downcasting. This would be a good spot for /// overhead of downcasting. This would be a good spot for
// /// optimization. /// optimization.
// fn convert_vec_to_context_element(array: &Vec<serde_json::Value>) -> Vec<&dyn ContextElement> { fn convert_vec_to_context_element(array: &Vec<serde_json::Value>) -> Vec<&dyn ContextElement> {
// array.iter().map(|v| v as _).collect() array.iter().map(|v| v as _).collect()
// } }
#[derive(Debug)] #[derive(Debug)]
enum JsonNumber { enum JsonNumber {