Switch the renderer over to using the new is_truthy value and add the injection of $idx and $len into the context tree.
This commit is contained in:
		
							parent
							
								
									966499db76
								
							
						
					
					
						commit
						c09393da80
					
				| @ -6,6 +6,7 @@ use crate::renderer::Renderable; | ||||
| use crate::renderer::Truthiness; | ||||
| use crate::renderer::WalkError; | ||||
| use crate::{parser::Filter, parser::OwnedLiteral, renderer::Walkable}; | ||||
| use std::convert::TryInto; | ||||
| 
 | ||||
| use std::cmp::Ordering; | ||||
| 
 | ||||
| @ -21,10 +22,11 @@ pub struct IterationContext { | ||||
| } | ||||
| 
 | ||||
| impl IterationContext { | ||||
|     pub fn new(idx: u64, len: u64) -> Self { | ||||
|     pub fn new(idx: usize, len: usize) -> Self { | ||||
|         // TODO: it would be nice to handle usize vs u64 better
 | ||||
|         IterationContext { | ||||
|             idx: OwnedLiteral::LPositiveInteger(idx), | ||||
|             len: OwnedLiteral::LPositiveInteger(len), | ||||
|             idx: OwnedLiteral::LPositiveInteger(idx.try_into().unwrap()), | ||||
|             len: OwnedLiteral::LPositiveInteger(len.try_into().unwrap()), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -13,6 +13,7 @@ use crate::renderer::errors::RenderError; | ||||
| use crate::renderer::errors::WalkError; | ||||
| use crate::renderer::inline_partial_tree::extract_inline_partials; | ||||
| use crate::renderer::inline_partial_tree::InlinePartialTreeElement; | ||||
| use crate::renderer::iteration_context::IterationContext; | ||||
| use crate::renderer::parameters_context::ParametersContext; | ||||
| use crate::renderer::walking::walk_path; | ||||
| use std::collections::HashMap; | ||||
| @ -150,58 +151,93 @@ impl<'a> DustRenderer<'a> { | ||||
|                 match val { | ||||
|                     Err(WalkError::CantWalk) => return Ok("".to_owned()), | ||||
|                     Ok(final_val) => { | ||||
|                         let loop_elements = final_val.get_loop_elements(); | ||||
|                         if loop_elements.is_empty() { | ||||
|                             return Ok("".to_owned()); | ||||
|                         return if final_val.is_truthy() { | ||||
|                             final_val.render(&Self::preprocess_filters(&reference.filters)) | ||||
|                         } else { | ||||
|                             return final_val.render(&Self::preprocess_filters(&reference.filters)); | ||||
|                         } | ||||
|                             Ok("".to_owned()) | ||||
|                         }; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             DustTag::DTSection(container) => { | ||||
|                 let val = walk_path(breadcrumbs, &container.path.keys); | ||||
|                 let loop_elements: Vec<&dyn ContextElement> = Self::get_loop_elements(val); | ||||
|                 if loop_elements.is_empty() { | ||||
|                     // Oddly enough if the value is falsey (like
 | ||||
|                     // an empty array or null), Dust uses the
 | ||||
|                     // original context before walking the path as
 | ||||
|                     // the context for rendering the else block
 | ||||
|                     return self.render_maybe_body(&container.else_contents, breadcrumbs, blocks); | ||||
|                 } else { | ||||
|                     match &container.contents { | ||||
|                         None => return Ok("".to_owned()), | ||||
|                         Some(body) => { | ||||
|                             let rendered_results: Result<Vec<String>, RenderError> = loop_elements | ||||
|                                 .into_iter() | ||||
|                                 .map(|array_elem| { | ||||
|                                     let mut new_breadcumbs = breadcrumbs.clone(); | ||||
|                                     new_breadcumbs.push(array_elem); | ||||
|                                     self.render_body(&body, &new_breadcumbs, blocks) | ||||
|                                 }) | ||||
|                                 .collect(); | ||||
|                             let rendered_slice: &[String] = &rendered_results?; | ||||
|                             return Ok(rendered_slice.join("")); | ||||
|                         } | ||||
|                 match val { | ||||
|                     Err(WalkError::CantWalk) => { | ||||
|                         return self.render_maybe_body( | ||||
|                             &container.else_contents, | ||||
|                             breadcrumbs, | ||||
|                             blocks, | ||||
|                         ); | ||||
|                     } | ||||
|                     Ok(final_val) => { | ||||
|                         return if final_val.is_truthy() { | ||||
|                             match &container.contents { | ||||
|                                 // If the body is empty, just shortcut
 | ||||
|                                 // to an empty string now rather than
 | ||||
|                                 // generating intermediate contexts
 | ||||
|                                 // and iterating for nothing.
 | ||||
|                                 None => Ok("".to_owned()), | ||||
|                                 Some(body) => { | ||||
|                                     let loop_elements: Vec<&dyn ContextElement> = | ||||
|                                         final_val.get_loop_elements(); | ||||
|                                     if loop_elements.is_empty() { | ||||
|                                         // Scalar value
 | ||||
|                                         let mut new_breadcrumbs = breadcrumbs.clone(); | ||||
|                                         new_breadcrumbs.push(final_val); | ||||
|                                         self.render_body(body, &new_breadcrumbs, blocks) | ||||
|                                     } else { | ||||
|                                         // Array-like value
 | ||||
|                                         let total_length = loop_elements.len(); | ||||
|                                         let rendered_results: Result<Vec<String>, RenderError> = | ||||
|                                             loop_elements | ||||
|                                                 .into_iter() | ||||
|                                                 .enumerate() | ||||
|                                                 .map(|(i, array_elem)| { | ||||
|                                                     let injected_context = | ||||
|                                                         IterationContext::new(i, total_length); | ||||
|                                                     let mut new_breadcrumbs = breadcrumbs.clone(); | ||||
|                                                     new_breadcrumbs.push(&injected_context); | ||||
|                                                     new_breadcrumbs.push(array_elem); | ||||
|                                                     self.render_body( | ||||
|                                                         &body, | ||||
|                                                         &new_breadcrumbs, | ||||
|                                                         blocks, | ||||
|                                                     ) | ||||
|                                                 }) | ||||
|                                                 .collect(); | ||||
|                                         let rendered_slice: &[String] = &rendered_results?; | ||||
|                                         return Ok(rendered_slice.join("")); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } else { | ||||
|                             // Oddly enough if the value is falsey (like
 | ||||
|                             // an empty array or null), Dust uses the
 | ||||
|                             // original context before walking the path as
 | ||||
|                             // the context for rendering the else block
 | ||||
|                             return self.render_maybe_body( | ||||
|                                 &container.else_contents, | ||||
|                                 breadcrumbs, | ||||
|                                 blocks, | ||||
|                             ); | ||||
|                         }; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             DustTag::DTExists(container) => { | ||||
|                 let val = walk_path(breadcrumbs, &container.path.keys); | ||||
|                 let loop_elements: Vec<&dyn ContextElement> = Self::get_loop_elements(val); | ||||
|                 return if loop_elements.is_empty() { | ||||
|                     self.render_maybe_body(&container.else_contents, breadcrumbs, blocks) | ||||
|                 } else { | ||||
|                 return if val.map(|v| v.is_truthy()).unwrap_or(false) { | ||||
|                     self.render_maybe_body(&container.contents, breadcrumbs, blocks) | ||||
|                 } else { | ||||
|                     self.render_maybe_body(&container.else_contents, breadcrumbs, blocks) | ||||
|                 }; | ||||
|             } | ||||
|             DustTag::DTNotExists(container) => { | ||||
|                 let val = walk_path(breadcrumbs, &container.path.keys); | ||||
|                 let loop_elements: Vec<&dyn ContextElement> = Self::get_loop_elements(val); | ||||
|                 return if !loop_elements.is_empty() { | ||||
|                     self.render_maybe_body(&container.else_contents, breadcrumbs, blocks) | ||||
|                 } else { | ||||
|                 return if !val.map(|v| v.is_truthy()).unwrap_or(false) { | ||||
|                     self.render_maybe_body(&container.contents, breadcrumbs, blocks) | ||||
|                 } else { | ||||
|                     self.render_maybe_body(&container.else_contents, breadcrumbs, blocks) | ||||
|                 }; | ||||
|             } | ||||
|             DustTag::DTPartial(partial) => { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander