use crate::renderer::context_element::CompareContextElement; use crate::renderer::context_element::ContextElement; use crate::renderer::Loopable; use crate::renderer::RenderError; 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; /// An injected context for $idx and $len /// /// Functions the same as the injected parameters contexts for /// helpers/partials with parameters but this has no need for storing /// breadcrumbs since its simply storing two integers. #[derive(Debug, Clone)] pub struct IterationContext { idx: OwnedLiteral, len: OwnedLiteral, } impl IterationContext { pub fn new(idx: usize, len: usize) -> Self { // TODO: it would be nice to handle usize vs u64 better IterationContext { idx: OwnedLiteral::LPositiveInteger(idx.try_into().unwrap()), len: OwnedLiteral::LPositiveInteger(len.try_into().unwrap()), } } } impl ContextElement for IterationContext {} impl Truthiness for IterationContext { fn is_truthy(&self) -> bool { // TODO: Would this even ever be called? Won't matter, but I'd // like to know. Since it is injected 1 above the current // context, we wouldn't be able to access it with `{.}`. true } } impl Renderable for IterationContext { fn render(&self, _filters: &Vec) -> Result { // TODO: Would this even ever be called? Won't matter, but I'd // like to know. Since it is injected 1 above the current // context, we wouldn't be able to access it with `{.}`. Ok("[object Object]".to_owned()) } } impl Loopable for IterationContext { fn get_loop_elements(&self) -> Vec<&dyn ContextElement> { // TODO: Would this even ever be called? Won't matter, but I'd // like to know. Since it is injected 1 above the current // context, we wouldn't be able to access it with `{.}`. Vec::new() } } impl Walkable for IterationContext { fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> { match segment { "$idx" => Ok(&self.idx), "$len" => Ok(&self.len), _ => Err(WalkError::CantWalk), } } fn is_pseudo_element(&self) -> bool { true } } impl CompareContextElement for IterationContext { fn equals(&self, other: &dyn ContextElement) -> bool { // TODO: Does this ever happen? perhaps I should have a panic here. false } fn partial_compare(&self, other: &dyn ContextElement) -> Option { // TODO: Does this ever happen? perhaps I should have a panic here. None } }