diff --git a/minijinja/src/context.rs b/minijinja/src/context.rs index 26ccbf16..86050f39 100644 --- a/minijinja/src/context.rs +++ b/minijinja/src/context.rs @@ -1,6 +1,28 @@ #[cfg(test)] use similar_asserts::assert_eq; +/// Hidden utility module for the [`context!`] macro. +#[doc(hidden)] +pub mod __context { + use crate::key::Key; + use crate::value::{RcType, Value, ValueMap, ValueRepr}; + + #[inline(always)] + pub fn make() -> ValueMap { + ValueMap::default() + } + + #[inline(always)] + pub fn add(ctx: &mut ValueMap, key: &'static str, value: Value) { + ctx.insert(Key::Str(key), value); + } + + #[inline(always)] + pub fn build(ctx: ValueMap) -> Value { + ValueRepr::Map(RcType::new(ctx)).into() + } +} + /// Creates a template context with keys and values. /// /// ```rust @@ -37,25 +59,29 @@ use similar_asserts::assert_eq; /// ``` #[macro_export] macro_rules! context { + () => { + $crate::__context::build($crate::__context::make()) + }; ( $($key:ident $(=> $value:expr)?),* $(,)? ) => {{ - let mut ctx = std::collections::BTreeMap::default(); + let mut ctx = $crate::__context::make(); $( - $crate::__pair!(ctx, $key $(, $value)?); + $crate::__context_pair!(ctx, $key $(, $value)?); )* - $crate::value::Value::from(ctx) + $crate::__context::build(ctx) }} } #[macro_export] #[doc(hidden)] -macro_rules! __pair { +macro_rules! __context_pair { ($ctx:ident, $key:ident) => {{ - $crate::__pair!($ctx, $key, $key); + $crate::__context_pair!($ctx, $key, $key); }}; ($ctx:ident, $key:ident, $value:expr) => { - $ctx.insert( + $crate::__context::add( + &mut $ctx, stringify!($key), $crate::value::Value::from_serializable(&$value), ); diff --git a/minijinja/src/functions.rs b/minijinja/src/functions.rs index c693efdf..c4469b30 100644 --- a/minijinja/src/functions.rs +++ b/minijinja/src/functions.rs @@ -174,8 +174,8 @@ mod builtins { step: Option, ) -> Result, Error> { let rng = match upper { - Some(upper) => (lower..upper), - None => (0..lower), + Some(upper) => lower..upper, + None => 0..lower, }; Ok(if let Some(step) = step { rng.step_by(step as usize).collect() diff --git a/minijinja/src/value.rs b/minijinja/src/value.rs index b0781971..70f27cd4 100644 --- a/minijinja/src/value.rs +++ b/minijinja/src/value.rs @@ -95,10 +95,10 @@ pub(crate) type RcType = std::rc::Rc; const VALUE_HANDLE_MARKER: &str = "\x01__minijinja_ValueHandle"; #[cfg(feature = "preserve_order")] -pub(crate) type ValueMap = indexmap::IndexMap; +pub(crate) type ValueMap = indexmap::IndexMap, Value>; #[cfg(not(feature = "preserve_order"))] -pub(crate) type ValueMap = std::collections::BTreeMap; +pub(crate) type ValueMap = std::collections::BTreeMap, Value>; thread_local! { static INTERNAL_SERIALIZATION: AtomicBool = AtomicBool::new(false); @@ -261,7 +261,7 @@ pub(crate) enum ValueRepr { SafeString(RcType), Bytes(RcType>), Seq(RcType>), - Map(RcType, Value>>), + Map(RcType), Dynamic(RcType), } @@ -1470,7 +1470,7 @@ impl ser::SerializeTupleVariant for SerializeTupleVariant { } struct SerializeMap { - entries: ValueMap, Value>, + entries: ValueMap, key: Option>, } @@ -1518,7 +1518,7 @@ impl ser::SerializeMap for SerializeMap { struct SerializeStruct { name: &'static str, - fields: ValueMap, Value>, + fields: ValueMap, } impl ser::SerializeStruct for SerializeStruct { @@ -1555,7 +1555,7 @@ impl ser::SerializeStruct for SerializeStruct { struct SerializeStructVariant { variant: &'static str, - map: ValueMap, Value>, + map: ValueMap, } impl ser::SerializeStructVariant for SerializeStructVariant { @@ -1613,9 +1613,9 @@ enum ValueIteratorState { Empty, Seq(usize, RcType>), #[cfg(not(feature = "preserve_order"))] - Map(Option>, RcType, Value>>), + Map(Option>, RcType), #[cfg(feature = "preserve_order")] - Map(usize, RcType, Value>>), + Map(usize, RcType), } impl ValueIteratorState {