minijinja/value/
mod.rs

1//! Provides a dynamic value type abstraction.
2//!
3//! This module gives access to a dynamically typed value which is used by
4//! the template engine during execution.
5//!
6//! For the most part the existence of the value type can be ignored as
7//! MiniJinja will perform the necessary conversions for you.  For instance
8//! if you write a filter that converts a string you can directly declare the
9//! filter to take a [`String`].  However for some more advanced use cases it's
10//! useful to know that this type exists.
11//!
12//! # Basic Value Conversions
13//!
14//! Values are typically created via the [`From`] trait:
15//!
16//! ```
17//! use std::collections::BTreeMap;
18//! # use minijinja::value::Value;
19//! let int_value = Value::from(42);
20//! let none_value = Value::from(());
21//! let true_value = Value::from(true);
22//! let map = Value::from({
23//!     let mut m = BTreeMap::new();
24//!     m.insert("foo", 1);
25//!     m.insert("bar", 2);
26//!     m
27//! });
28//! ```
29//!
30//! Or via the [`FromIterator`] trait which can create sequences or maps.  When
31//! given a tuple it creates maps, otherwise it makes a sequence.
32//!
33//! ```
34//! # use minijinja::value::Value;
35//! // collection into a sequence
36//! let value: Value = (1..10).into_iter().collect();
37//!
38//! // collection into a map
39//! let value: Value = [("key", "value")].into_iter().collect();
40//! ```
41//!
42//! For certain types of iterators (`Send` + `Sync` + `'static`) it's also
43//! possible to make the value lazily iterate over the value by using the
44//! [`Value::make_iterable`] function instead.  Whenever the value requires
45//! iteration, the function is called to create that iterator.
46//!
47//! ```
48//! # use minijinja::value::Value;
49//! let value: Value = Value::make_iterable(|| 1..10);
50//! ```
51//!
52//! To to into the inverse directly the various [`TryFrom`]
53//! implementations can be used:
54//!
55//! ```
56//! # use minijinja::value::Value;
57//! use std::convert::TryFrom;
58//! let v = u64::try_from(Value::from(42)).unwrap();
59//! ```
60//!
61//! The special [`Undefined`](Value::UNDEFINED) value also exists but does not
62//! have a rust equivalent.  It can be created via the [`UNDEFINED`](Value::UNDEFINED)
63//! constant.
64//!
65//! # Collections
66//!
67//! The standard library's collection types such as
68//! [`HashMap`](std::collections::HashMap), [`Vec`] and various others from the
69//! collections module are implemented are objects.  There is a cavet here which is
70//! that maps can only have string or [`Value`] as key.  The values in the collections
71//! are lazily converted into value when accessed or iterated over.   These types can
72//! be constructed either from [`Value::from`] or [`Value::from_object`].  Because the
73//! types are boxed unchanged, you can also downcast them.
74//!
75//! ```rust
76//! # use minijinja::Value;
77//! let vec = Value::from(vec![1i32, 2, 3, 4]);
78//! let vec_ref = vec.downcast_object_ref::<Vec<i32>>().unwrap();
79//! assert_eq!(vec_ref, &vec![1, 2, 3, 4]);
80//! ```
81//!
82//! **Caveat:** for convenience reasons maps with `&str` keys can be stored.  The keys
83//! however are converted into `Arc<str>`.
84//!
85//! # Serde Conversions
86//!
87//! MiniJinja will usually however create values via an indirection via [`serde`] when
88//! a template is rendered or an expression is evaluated.  This can also be
89//! triggered manually by using the [`Value::from_serialize`] method:
90//!
91//! ```
92//! # use minijinja::value::Value;
93//! let value = Value::from_serialize(&[1, 2, 3]);
94//! ```
95//!
96//! The inverse of that operation is to pass a value directly as serializer to
97//! a type that supports deserialization.  This requires the `deserialization`
98//! feature.
99//!
100#![cfg_attr(
101    feature = "deserialization",
102    doc = r"
103```
104# use minijinja::value::Value;
105use serde::Deserialize;
106let value = Value::from(vec![1, 2, 3]);
107let vec = Vec::<i32>::deserialize(value).unwrap();
108```
109"
110)]
111//!
112//! # Value Function Arguments
113//!
114//! [Filters](crate::filters) and [tests](crate::tests) can take values as arguments
115//! but optionally also rust types directly.  This conversion for function arguments
116//! is performed by the [`FunctionArgs`] and related traits ([`ArgType`], [`FunctionResult`]).
117//!
118//! # Memory Management
119//!
120//! Values are immutable objects which are internally reference counted which
121//! means they can be copied relatively cheaply.  Special care must be taken
122//! so that cycles are not created to avoid causing memory leaks.
123//!
124//! # HTML Escaping
125//!
126//! MiniJinja inherits the general desire to be clever about escaping.  For this
127//! purpose a value will (when auto escaping is enabled) always be escaped.  To
128//! prevent this behavior the [`safe`](crate::filters::safe) filter can be used
129//! in the template.  Outside of templates the [`Value::from_safe_string`] method
130//! can be used to achieve the same result.
131//!
132//! # Dynamic Objects
133//!
134//! Values can also hold "dynamic" objects.  These are objects which implement the
135//! [`Object`] trait.  These can be used to implement dynamic functionality such
136//! as stateful values and more.  Dynamic objects are internally also used to
137//! implement the special `loop` variable, macros and similar things.
138//!
139//! To create a [`Value`] from a dynamic object use [`Value::from_object`],
140//! [`Value::from_dyn_object`]:
141//!
142//! ```rust
143//! # use std::sync::Arc;
144//! # use minijinja::value::{Value, Object, DynObject};
145//! #[derive(Debug)]
146//! struct Foo;
147//!
148//! impl Object for Foo {
149//!     /* implementation */
150//! }
151//!
152//! let value = Value::from_object(Foo);
153//! let value = Value::from_dyn_object(Arc::new(Foo));
154//! ```
155//!
156//! # Invalid Values
157//!
158//! MiniJinja knows the concept of an "invalid value".  These are rare in practice
159//! and should not be used, but they are needed in some situations.  An invalid value
160//! looks like a value but working with that value in the context of the engine will
161//! fail in most situations.  In principle an invalid value is a value that holds an
162//! error internally.  It's created with [`From`]:
163//!
164//! ```
165//! use minijinja::{Value, Error, ErrorKind};
166//! let error = Error::new(ErrorKind::InvalidOperation, "failed to generate an item");
167//! let invalid_value = Value::from(error);
168//! ```
169//!
170//! Invalid values are typically encountered in the following situations:
171//!
172//! - serialization fails with an error: this is the case when a value is crated
173//!   via [`Value::from_serialize`] and the underlying [`Serialize`] implementation
174//!   fails with an error.
175//! - fallible iteration: there might be situations where an iterator cannot indicate
176//!   failure ahead of iteration and must abort.  In that case the only option an
177//!   iterator in MiniJinja has is to create an invalid value.
178//!
179//! It's generally recommende to ignore the existence of invalid objects and let them
180//! fail naturally as they are encountered.
181//!
182//! # Notes on Bytes and Strings
183//!
184//! Usually one would pass strings to templates as Jinja is entirely based on string
185//! rendering.  However there are situations where it can be useful to pass bytes instead.
186//! As such MiniJinja allows a value type to carry bytes even though there is no syntax
187//! within the template language to create a byte literal.
188//!
189//! When rendering bytes as strings, MiniJinja will attempt to interpret them as
190//! lossy utf-8.  This is a bit different to Jinja2 which in Python 3 stopped
191//! rendering byte strings as strings.  This is an intentional change that was
192//! deemed acceptable given how infrequently bytes are used but how relatively
193//! commonly bytes are often holding "almost utf-8" in templates.  Most
194//! conversions to strings also will do almost the same.  The debug rendering of
195//! bytes however is different and bytes are not iterable.  Like strings however
196//! they can be sliced and indexed, but they will be sliced by bytes and not by
197//! characters.
198
199// this module is based on the content module in insta which in turn is based
200// on the content module in serde::private::ser.
201
202use core::str;
203use std::cell::{Cell, RefCell};
204use std::cmp::Ordering;
205use std::collections::BTreeMap;
206use std::fmt;
207use std::hash::{Hash, Hasher};
208use std::sync::{Arc, Mutex};
209
210use serde::ser::{Serialize, Serializer};
211
212use crate::error::{Error, ErrorKind};
213use crate::functions;
214use crate::utils::OnDrop;
215use crate::value::ops::as_f64;
216use crate::value::serialize::transform;
217use crate::vm::State;
218
219pub use crate::value::argtypes::{from_args, ArgType, FunctionArgs, FunctionResult, Kwargs, Rest};
220pub use crate::value::object::{DynObject, Enumerator, Object, ObjectExt, ObjectRepr};
221
222#[macro_use]
223mod type_erase;
224mod argtypes;
225#[cfg(feature = "deserialization")]
226mod deserialize;
227pub(crate) mod merge_object;
228pub(crate) mod namespace_object;
229mod object;
230pub(crate) mod ops;
231mod serialize;
232#[cfg(feature = "key_interning")]
233mod string_interning;
234
235#[cfg(feature = "deserialization")]
236pub use self::deserialize::ViaDeserialize;
237
238// We use in-band signalling to roundtrip some internal values.  This is
239// not ideal but unfortunately there is no better system in serde today.
240const VALUE_HANDLE_MARKER: &str = "\x01__minijinja_ValueHandle";
241
242#[cfg(feature = "preserve_order")]
243pub(crate) type ValueMap = indexmap::IndexMap<Value, Value>;
244
245#[cfg(not(feature = "preserve_order"))]
246pub(crate) type ValueMap = std::collections::BTreeMap<Value, Value>;
247
248#[inline(always)]
249pub(crate) fn value_map_with_capacity(capacity: usize) -> ValueMap {
250    #[cfg(not(feature = "preserve_order"))]
251    {
252        let _ = capacity;
253        ValueMap::new()
254    }
255    #[cfg(feature = "preserve_order")]
256    {
257        ValueMap::with_capacity(crate::utils::untrusted_size_hint(capacity))
258    }
259}
260
261thread_local! {
262    static INTERNAL_SERIALIZATION: Cell<bool> = const { Cell::new(false) };
263
264    // This should be an AtomicU64 but sadly 32bit targets do not necessarily have
265    // AtomicU64 available.
266    static LAST_VALUE_HANDLE: Cell<u32> = const { Cell::new(0) };
267    static VALUE_HANDLES: RefCell<BTreeMap<u32, Value>> = RefCell::new(BTreeMap::new());
268}
269
270/// Function that returns true when serialization for [`Value`] is taking place.
271///
272/// MiniJinja internally creates [`Value`] objects from all values passed to the
273/// engine.  It does this by going through the regular serde serialization trait.
274/// In some cases users might want to customize the serialization specifically for
275/// MiniJinja because they want to tune the object for the template engine
276/// independently of what is normally serialized to disk.
277///
278/// This function returns `true` when MiniJinja is serializing to [`Value`] and
279/// `false` otherwise.  You can call this within your own [`Serialize`]
280/// implementation to change the output format.
281///
282/// This is particularly useful as serialization for MiniJinja does not need to
283/// support deserialization.  So it becomes possible to completely change what
284/// gets sent there, even at the cost of serializing something that cannot be
285/// deserialized.
286pub fn serializing_for_value() -> bool {
287    INTERNAL_SERIALIZATION.with(|flag| flag.get())
288}
289
290/// Enables value optimizations.
291///
292/// If `key_interning` is enabled, this turns on that feature, otherwise
293/// it becomes a noop.
294#[inline(always)]
295pub(crate) fn value_optimization() -> impl Drop {
296    #[cfg(feature = "key_interning")]
297    {
298        crate::value::string_interning::use_string_cache()
299    }
300    #[cfg(not(feature = "key_interning"))]
301    {
302        OnDrop::new(|| {})
303    }
304}
305
306fn mark_internal_serialization() -> impl Drop {
307    let old = INTERNAL_SERIALIZATION.with(|flag| {
308        let old = flag.get();
309        flag.set(true);
310        old
311    });
312    OnDrop::new(move || {
313        if !old {
314            INTERNAL_SERIALIZATION.with(|flag| flag.set(false));
315        }
316    })
317}
318
319/// Describes the kind of value.
320#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
321#[non_exhaustive]
322pub enum ValueKind {
323    /// The value is undefined
324    Undefined,
325    /// The value is the none singleton (`()`)
326    None,
327    /// The value is a [`bool`]
328    Bool,
329    /// The value is a number of a supported type.
330    Number,
331    /// The value is a string.
332    String,
333    /// The value is a byte array.
334    Bytes,
335    /// The value is an array of other values.
336    Seq,
337    /// The value is a key/value mapping.
338    Map,
339    /// An iterable
340    Iterable,
341    /// A plain object without specific behavior.
342    Plain,
343    /// This value is invalid (holds an error).
344    ///
345    /// This can happen when a serialization error occurred or the engine
346    /// encountered a failure in a place where an error can otherwise not
347    /// be produced.  Interacting with such values in the context of the
348    /// template evaluation process will attempt to propagate the error.
349    Invalid,
350}
351
352impl fmt::Display for ValueKind {
353    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354        f.write_str(match *self {
355            ValueKind::Undefined => "undefined",
356            ValueKind::None => "none",
357            ValueKind::Bool => "bool",
358            ValueKind::Number => "number",
359            ValueKind::String => "string",
360            ValueKind::Bytes => "bytes",
361            ValueKind::Seq => "sequence",
362            ValueKind::Map => "map",
363            ValueKind::Iterable => "iterator",
364            ValueKind::Plain => "plain object",
365            ValueKind::Invalid => "invalid value",
366        })
367    }
368}
369
370/// Type type of string
371#[derive(Copy, Clone, Debug)]
372pub(crate) enum StringType {
373    Normal,
374    Safe,
375}
376
377/// Wraps an internal copyable value but marks it as packed.
378///
379/// This is used for `i128`/`u128` in the value repr to avoid
380/// the excessive 16 byte alignment.
381#[derive(Copy)]
382#[repr(packed)]
383pub(crate) struct Packed<T: Copy>(pub T);
384
385impl<T: Copy> Clone for Packed<T> {
386    fn clone(&self) -> Self {
387        *self
388    }
389}
390
391/// Max size of a small str.
392///
393/// Logic: Value is 24 bytes. 1 byte is for the disciminant. One byte is
394/// needed for the small str length.
395const SMALL_STR_CAP: usize = 22;
396
397/// Helper to store string data inline.
398#[derive(Clone)]
399pub(crate) struct SmallStr {
400    len: u8,
401    buf: [u8; SMALL_STR_CAP],
402}
403
404impl SmallStr {
405    pub fn try_new(s: &str) -> Option<SmallStr> {
406        let len = s.len();
407        if len <= SMALL_STR_CAP {
408            let mut buf = [0u8; SMALL_STR_CAP];
409            buf[..len].copy_from_slice(s.as_bytes());
410            Some(SmallStr {
411                len: len as u8,
412                buf,
413            })
414        } else {
415            None
416        }
417    }
418
419    pub fn as_str(&self) -> &str {
420        // SAFETY: This is safe because we only place well-formed utf-8 strings
421        unsafe { std::str::from_utf8_unchecked(&self.buf[..self.len as usize]) }
422    }
423
424    pub fn is_empty(&self) -> bool {
425        self.len == 0
426    }
427}
428
429#[derive(Clone)]
430pub(crate) enum ValueRepr {
431    Undefined,
432    Bool(bool),
433    U64(u64),
434    I64(i64),
435    F64(f64),
436    None,
437    Invalid(Arc<Error>),
438    U128(Packed<u128>),
439    I128(Packed<i128>),
440    String(Arc<str>, StringType),
441    SmallStr(SmallStr),
442    Bytes(Arc<Vec<u8>>),
443    Object(DynObject),
444}
445
446impl fmt::Debug for ValueRepr {
447    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
448        match self {
449            ValueRepr::Undefined => f.write_str("undefined"),
450            ValueRepr::Bool(val) => fmt::Debug::fmt(val, f),
451            ValueRepr::U64(val) => fmt::Debug::fmt(val, f),
452            ValueRepr::I64(val) => fmt::Debug::fmt(val, f),
453            ValueRepr::F64(val) => fmt::Debug::fmt(val, f),
454            ValueRepr::None => f.write_str("none"),
455            ValueRepr::Invalid(ref val) => write!(f, "<invalid value: {}>", val),
456            ValueRepr::U128(val) => fmt::Debug::fmt(&{ val.0 }, f),
457            ValueRepr::I128(val) => fmt::Debug::fmt(&{ val.0 }, f),
458            ValueRepr::String(val, _) => fmt::Debug::fmt(val, f),
459            ValueRepr::SmallStr(val) => fmt::Debug::fmt(val.as_str(), f),
460            ValueRepr::Bytes(val) => {
461                write!(f, "b'")?;
462                for &b in val.iter() {
463                    if b == b'"' {
464                        write!(f, "\"")?
465                    } else {
466                        write!(f, "{}", b.escape_ascii())?;
467                    }
468                }
469                write!(f, "'")
470            }
471            ValueRepr::Object(val) => val.render(f),
472        }
473    }
474}
475
476impl Hash for Value {
477    fn hash<H: Hasher>(&self, state: &mut H) {
478        match &self.0 {
479            ValueRepr::None | ValueRepr::Undefined => 0u8.hash(state),
480            ValueRepr::String(ref s, _) => s.hash(state),
481            ValueRepr::SmallStr(s) => s.as_str().hash(state),
482            ValueRepr::Bool(b) => b.hash(state),
483            ValueRepr::Invalid(ref e) => (e.kind(), e.detail()).hash(state),
484            ValueRepr::Bytes(b) => b.hash(state),
485            ValueRepr::Object(d) => d.hash(state),
486            ValueRepr::U64(_)
487            | ValueRepr::I64(_)
488            | ValueRepr::F64(_)
489            | ValueRepr::U128(_)
490            | ValueRepr::I128(_) => {
491                if let Ok(val) = i64::try_from(self.clone()) {
492                    val.hash(state)
493                } else {
494                    as_f64(self, true).map(|x| x.to_bits()).hash(state)
495                }
496            }
497        }
498    }
499}
500
501/// Represents a dynamically typed value in the template engine.
502#[derive(Clone)]
503pub struct Value(pub(crate) ValueRepr);
504
505impl PartialEq for Value {
506    fn eq(&self, other: &Self) -> bool {
507        match (&self.0, &other.0) {
508            (ValueRepr::None, ValueRepr::None) => true,
509            (ValueRepr::Undefined, ValueRepr::Undefined) => true,
510            (ValueRepr::String(ref a, _), ValueRepr::String(ref b, _)) => a == b,
511            (ValueRepr::SmallStr(a), ValueRepr::SmallStr(b)) => a.as_str() == b.as_str(),
512            (ValueRepr::Bytes(a), ValueRepr::Bytes(b)) => a == b,
513            _ => match ops::coerce(self, other, false) {
514                Some(ops::CoerceResult::F64(a, b)) => a == b,
515                Some(ops::CoerceResult::I128(a, b)) => a == b,
516                Some(ops::CoerceResult::Str(a, b)) => a == b,
517                None => {
518                    if let (Some(a), Some(b)) = (self.as_object(), other.as_object()) {
519                        if a.is_same_object(b) {
520                            return true;
521                        }
522                        match (a.repr(), b.repr()) {
523                            (ObjectRepr::Map, ObjectRepr::Map) => {
524                                // only if we have known lengths can we compare the enumerators
525                                // ahead of time.  This function has a fallback for when a
526                                // map has an unknown length.  That's generally a bad idea, but
527                                // it makes sense supporting regardless as silent failures are
528                                // not a lot of fun.
529                                let mut need_length_fallback = true;
530                                if let (Some(a_len), Some(b_len)) =
531                                    (a.enumerator_len(), b.enumerator_len())
532                                {
533                                    if a_len != b_len {
534                                        return false;
535                                    }
536                                    need_length_fallback = false;
537                                }
538                                let mut a_count = 0;
539                                if !a.try_iter_pairs().map_or(false, |mut ak| {
540                                    ak.all(|(k, v1)| {
541                                        a_count += 1;
542                                        b.get_value(&k).map_or(false, |v2| v1 == v2)
543                                    })
544                                }) {
545                                    return false;
546                                }
547                                if !need_length_fallback {
548                                    true
549                                } else {
550                                    a_count == b.try_iter().map_or(0, |x| x.count())
551                                }
552                            }
553                            (
554                                ObjectRepr::Seq | ObjectRepr::Iterable,
555                                ObjectRepr::Seq | ObjectRepr::Iterable,
556                            ) => {
557                                if let (Some(ak), Some(bk)) = (a.try_iter(), b.try_iter()) {
558                                    ak.eq(bk)
559                                } else {
560                                    false
561                                }
562                            }
563                            _ => false,
564                        }
565                    } else {
566                        false
567                    }
568                }
569            },
570        }
571    }
572}
573
574impl Eq for Value {}
575
576impl PartialOrd for Value {
577    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
578        Some(self.cmp(other))
579    }
580}
581
582fn f64_total_cmp(left: f64, right: f64) -> Ordering {
583    // this is taken from f64::total_cmp on newer rust versions
584    let mut left = left.to_bits() as i64;
585    let mut right = right.to_bits() as i64;
586    left ^= (((left >> 63) as u64) >> 1) as i64;
587    right ^= (((right >> 63) as u64) >> 1) as i64;
588    left.cmp(&right)
589}
590
591impl Ord for Value {
592    fn cmp(&self, other: &Self) -> Ordering {
593        let kind_ordering = self.kind().cmp(&other.kind());
594        if matches!(kind_ordering, Ordering::Less | Ordering::Greater) {
595            return kind_ordering;
596        }
597        match (&self.0, &other.0) {
598            (ValueRepr::None, ValueRepr::None) => Ordering::Equal,
599            (ValueRepr::Undefined, ValueRepr::Undefined) => Ordering::Equal,
600            (ValueRepr::String(ref a, _), ValueRepr::String(ref b, _)) => a.cmp(b),
601            (ValueRepr::SmallStr(a), ValueRepr::SmallStr(b)) => a.as_str().cmp(b.as_str()),
602            (ValueRepr::Bytes(a), ValueRepr::Bytes(b)) => a.cmp(b),
603            _ => match ops::coerce(self, other, false) {
604                Some(ops::CoerceResult::F64(a, b)) => f64_total_cmp(a, b),
605                Some(ops::CoerceResult::I128(a, b)) => a.cmp(&b),
606                Some(ops::CoerceResult::Str(a, b)) => a.cmp(b),
607                None => {
608                    if let (Some(a), Some(b)) = (self.as_object(), other.as_object()) {
609                        if a.is_same_object(b) {
610                            Ordering::Equal
611                        } else {
612                            match (a.repr(), b.repr()) {
613                                (ObjectRepr::Map, ObjectRepr::Map) => {
614                                    // This is not really correct.  Because the keys can be in arbitrary
615                                    // order this could just sort really weirdly as a result.  However
616                                    // we don't want to pay the cost of actually sorting the keys for
617                                    // ordering so we just accept this for now.
618                                    match (a.try_iter_pairs(), b.try_iter_pairs()) {
619                                        (Some(a), Some(b)) => a.cmp(b),
620                                        _ => unreachable!(),
621                                    }
622                                }
623                                (
624                                    ObjectRepr::Seq | ObjectRepr::Iterable,
625                                    ObjectRepr::Seq | ObjectRepr::Iterable,
626                                ) => match (a.try_iter(), b.try_iter()) {
627                                    (Some(a), Some(b)) => a.cmp(b),
628                                    _ => unreachable!(),
629                                },
630                                (_, _) => unreachable!(),
631                            }
632                        }
633                    } else {
634                        unreachable!()
635                    }
636                }
637            },
638        }
639    }
640}
641
642impl fmt::Debug for Value {
643    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
644        fmt::Debug::fmt(&self.0, f)
645    }
646}
647
648impl fmt::Display for Value {
649    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
650        match &self.0 {
651            ValueRepr::Undefined => Ok(()),
652            ValueRepr::Bool(val) => val.fmt(f),
653            ValueRepr::U64(val) => val.fmt(f),
654            ValueRepr::I64(val) => val.fmt(f),
655            ValueRepr::F64(val) => {
656                if val.is_nan() {
657                    f.write_str("NaN")
658                } else if val.is_infinite() {
659                    write!(f, "{}inf", if val.is_sign_negative() { "-" } else { "" })
660                } else {
661                    let mut num = val.to_string();
662                    if !num.contains('.') {
663                        num.push_str(".0");
664                    }
665                    write!(f, "{num}")
666                }
667            }
668            ValueRepr::None => f.write_str("none"),
669            ValueRepr::Invalid(ref val) => write!(f, "<invalid value: {}>", val),
670            ValueRepr::I128(val) => write!(f, "{}", { val.0 }),
671            ValueRepr::String(val, _) => write!(f, "{val}"),
672            ValueRepr::SmallStr(val) => write!(f, "{}", val.as_str()),
673            ValueRepr::Bytes(val) => write!(f, "{}", String::from_utf8_lossy(val)),
674            ValueRepr::U128(val) => write!(f, "{}", { val.0 }),
675            ValueRepr::Object(x) => write!(f, "{x}"),
676        }
677    }
678}
679
680impl Default for Value {
681    fn default() -> Value {
682        ValueRepr::Undefined.into()
683    }
684}
685
686/// Intern a string.
687///
688/// When the `key_interning` feature is in used, then MiniJinja will attempt to
689/// reuse strings in certain cases.  This function can be used to utilize the
690/// same functionality.  There is no guarantee that a string will be interned
691/// as there are heuristics involved for it.  Additionally the string interning
692/// will only work during the template engine execution (eg: within filters etc.).
693pub fn intern(s: &str) -> Arc<str> {
694    #[cfg(feature = "key_interning")]
695    {
696        crate::value::string_interning::try_intern(s)
697    }
698    #[cfg(not(feature = "key_interning"))]
699    {
700        Arc::from(s.to_string())
701    }
702}
703
704#[allow(clippy::len_without_is_empty)]
705impl Value {
706    /// The undefined value.
707    ///
708    /// This constant exists because the undefined type does not exist in Rust
709    /// and this is the only way to construct it.
710    pub const UNDEFINED: Value = Value(ValueRepr::Undefined);
711
712    /// Creates a value from something that can be serialized.
713    ///
714    /// This is the method that MiniJinja will generally use whenever a serializable
715    /// object is passed to one of the APIs that internally want to create a value.
716    /// For instance this is what [`context!`](crate::context) and
717    /// [`render`](crate::Template::render) will use.
718    ///
719    /// During serialization of the value, [`serializing_for_value`] will return
720    /// `true` which makes it possible to customize serialization for MiniJinja.
721    /// For more information see [`serializing_for_value`].
722    ///
723    /// ```
724    /// # use minijinja::value::Value;
725    /// let val = Value::from_serialize(&vec![1, 2, 3]);
726    /// ```
727    ///
728    /// This method does not fail but it might return a value that is not valid.  Such
729    /// values will when operated on fail in the template engine in most situations.
730    /// This for instance can happen if the underlying implementation of [`Serialize`]
731    /// fails.  There are also cases where invalid objects are silently hidden in the
732    /// engine today.  This is for instance the case for when keys are used in hash maps
733    /// that the engine cannot deal with.  Invalid values are considered an implementation
734    /// detail.  There is currently no API to validate a value.
735    ///
736    /// If the `deserialization` feature is enabled then the inverse of this method
737    /// is to use the [`Value`] type as serializer.  You can pass a value into the
738    /// [`deserialize`](serde::Deserialize::deserialize) method of a type that supports
739    /// serde deserialization.
740    pub fn from_serialize<T: Serialize>(value: T) -> Value {
741        let _serialization_guard = mark_internal_serialization();
742        let _optimization_guard = value_optimization();
743        transform(value)
744    }
745
746    /// Extracts a contained error.
747    ///
748    /// An invalid value carres an error internally and will reveal that error
749    /// at a later point when iteracted with.  This is used to carry
750    /// serialization errors or failures that happen when the engine otherwise
751    /// assumes an infallible operation such as iteration.
752    pub(crate) fn validate(self) -> Result<Value, Error> {
753        if let ValueRepr::Invalid(err) = self.0 {
754            // Today the API implies tghat errors are `Clone`, but we don't want to expose
755            // this as a functionality (yet?).
756            Err(Arc::try_unwrap(err).unwrap_or_else(|arc| (*arc).internal_clone()))
757        } else {
758            Ok(self)
759        }
760    }
761
762    /// Creates a value from a safe string.
763    ///
764    /// A safe string is one that will bypass auto escaping.  For instance if you
765    /// want to have the template engine render some HTML without the user having to
766    /// supply the `|safe` filter, you can use a value of this type instead.
767    ///
768    /// ```
769    /// # use minijinja::value::Value;
770    /// let val = Value::from_safe_string("<em>note</em>".into());
771    /// ```
772    pub fn from_safe_string(value: String) -> Value {
773        ValueRepr::String(Arc::from(value), StringType::Safe).into()
774    }
775
776    /// Creates a value from a byte vector.
777    ///
778    /// MiniJinja can hold on to bytes and has some limited built-in support for
779    /// working with them.  They are non iterable and not particularly useful
780    /// in the context of templates.  When they are stringified, they are assumed
781    /// to contain UTF-8 and will be treated as such.  They become more useful
782    /// when a filter can do something with them (eg: base64 encode them etc.).
783    ///
784    /// This method exists so that a value can be constructed as creating a
785    /// value from a `Vec<u8>` would normally just create a sequence.
786    pub fn from_bytes(value: Vec<u8>) -> Value {
787        ValueRepr::Bytes(value.into()).into()
788    }
789
790    /// Creates a value from a dynamic object.
791    ///
792    /// For more information see [`Object`].
793    ///
794    /// ```rust
795    /// # use minijinja::value::{Value, Object};
796    /// use std::fmt;
797    ///
798    /// #[derive(Debug)]
799    /// struct Thing {
800    ///     id: usize,
801    /// }
802    ///
803    /// impl Object for Thing {}
804    ///
805    /// let val = Value::from_object(Thing { id: 42 });
806    /// ```
807    pub fn from_object<T: Object + Send + Sync + 'static>(value: T) -> Value {
808        Value::from(ValueRepr::Object(DynObject::new(Arc::new(value))))
809    }
810
811    /// Like [`from_object`](Self::from_object) but for type erased dynamic objects.
812    ///
813    /// This especially useful if you have an object that has an `Arc<T>` to another
814    /// child object that you want to return as a `Arc<T>` turns into a [`DynObject`]
815    /// automatically.
816    ///
817    /// ```rust
818    /// # use std::sync::Arc;
819    /// # use minijinja::value::{Value, Object, Enumerator};
820    /// #[derive(Debug)]
821    /// pub struct HttpConfig {
822    ///     port: usize,
823    /// }
824    ///
825    /// #[derive(Debug)]
826    /// struct Config {
827    ///     http: Arc<HttpConfig>,
828    /// }
829    ///
830    /// impl Object for HttpConfig {
831    ///     fn enumerate(self: &Arc<Self>) -> Enumerator {
832    ///         Enumerator::Str(&["port"])
833    ///     }
834    ///
835    ///     fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
836    ///         match key.as_str()? {
837    ///             "port" => Some(Value::from(self.port)),
838    ///             _ => None,
839    ///         }
840    ///     }
841    /// }
842    ///
843    /// impl Object for Config {
844    ///     fn enumerate(self: &Arc<Self>) -> Enumerator {
845    ///         Enumerator::Str(&["http"])
846    ///     }
847    ///
848    ///     fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
849    ///         match key.as_str()? {
850    ///             "http" => Some(Value::from_dyn_object(self.http.clone())),
851    ///             _ => None
852    ///         }
853    ///     }
854    /// }
855    /// ```
856    pub fn from_dyn_object<T: Into<DynObject>>(value: T) -> Value {
857        Value::from(ValueRepr::Object(value.into()))
858    }
859
860    /// Creates a value that is an iterable.
861    ///
862    /// The function is invoked to create a new iterator every time the value is
863    /// iterated over.
864    ///
865    /// ```
866    /// # use minijinja::value::Value;
867    /// let val = Value::make_iterable(|| 0..10);
868    /// ```
869    ///
870    /// Iterators that implement [`ExactSizeIterator`] or have a matching lower and upper
871    /// bound on the [`Iterator::size_hint`] report a known `loop.length`.  Iterators that
872    /// do not fulfill these requirements will not.  The same is true for `revindex` and
873    /// similar properties.
874    pub fn make_iterable<I, T, F>(maker: F) -> Value
875    where
876        I: Iterator<Item = T> + Send + Sync + 'static,
877        T: Into<Value> + Send + Sync + 'static,
878        F: Fn() -> I + Send + Sync + 'static,
879    {
880        Value::make_object_iterable((), move |_| Box::new(maker().map(Into::into)))
881    }
882
883    /// Creates an iterable that iterates over the given value.
884    ///
885    /// This is similar to [`make_iterable`](Self::make_iterable) but it takes an extra
886    /// reference to a value it can borrow out from.  It's a bit less generic in that it
887    /// needs to return a boxed iterator of values directly.
888    ///
889    /// ```rust
890    /// # use minijinja::value::Value;
891    /// let val = Value::make_object_iterable(vec![1, 2, 3], |vec| {
892    ///     Box::new(vec.iter().copied().map(Value::from))
893    /// });
894    /// assert_eq!(val.to_string(), "[1, 2, 3]");
895    /// ````
896    pub fn make_object_iterable<T, F>(object: T, maker: F) -> Value
897    where
898        T: Send + Sync + 'static,
899        F: for<'a> Fn(&'a T) -> Box<dyn Iterator<Item = Value> + Send + Sync + 'a>
900            + Send
901            + Sync
902            + 'static,
903    {
904        struct Iterable<T, F> {
905            maker: F,
906            object: T,
907        }
908
909        impl<T, F> fmt::Debug for Iterable<T, F> {
910            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
911                f.debug_struct("<iterator>").finish()
912            }
913        }
914
915        impl<T, F> Object for Iterable<T, F>
916        where
917            T: Send + Sync + 'static,
918            F: for<'a> Fn(&'a T) -> Box<dyn Iterator<Item = Value> + Send + Sync + 'a>
919                + Send
920                + Sync
921                + 'static,
922        {
923            fn repr(self: &Arc<Self>) -> ObjectRepr {
924                ObjectRepr::Iterable
925            }
926
927            fn enumerate(self: &Arc<Self>) -> Enumerator {
928                struct Iter {
929                    iter: Box<dyn Iterator<Item = Value> + Send + Sync + 'static>,
930                    _object: DynObject,
931                }
932
933                impl Iterator for Iter {
934                    type Item = Value;
935
936                    fn next(&mut self) -> Option<Self::Item> {
937                        self.iter.next()
938                    }
939
940                    fn size_hint(&self) -> (usize, Option<usize>) {
941                        self.iter.size_hint()
942                    }
943                }
944
945                // SAFETY: this is safe because the object is kept alive by the iter
946                let iter = unsafe {
947                    std::mem::transmute::<
948                        Box<dyn Iterator<Item = _>>,
949                        Box<dyn Iterator<Item = _> + Send + Sync>,
950                    >((self.maker)(&self.object))
951                };
952                let _object = DynObject::new(self.clone());
953                Enumerator::Iter(Box::new(Iter { iter, _object }))
954            }
955        }
956
957        Value::from_object(Iterable { maker, object })
958    }
959
960    /// Creates a value from a one-shot iterator.
961    ///
962    /// This takes an iterator (yielding values that can be turned into a [`Value`])
963    /// and wraps it in a way that it turns into an iterable value.  From the view of
964    /// the template this can be iterated over exactly once for the most part once
965    /// exhausted.
966    ///
967    /// Such iterators are strongly recommended against in the general sense due to
968    /// their surprising behavior, but they can be useful for more advanced use
969    /// cases where data should be streamed into the template as it becomes available.
970    ///
971    /// Such iterators never have any size hints.
972    ///
973    /// ```
974    /// # use minijinja::value::Value;
975    /// let val = Value::make_one_shot_iterator(0..10);
976    /// ```
977    ///
978    /// Attempting to iterate over it a second time will not yield any more items.
979    pub fn make_one_shot_iterator<I, T>(iter: I) -> Value
980    where
981        I: Iterator<Item = T> + Send + Sync + 'static,
982        T: Into<Value> + Send + Sync + 'static,
983    {
984        let iter = Arc::new(Mutex::new(iter.fuse()));
985        Value::make_iterable(move || {
986            let iter = iter.clone();
987            std::iter::from_fn(move || iter.lock().unwrap().next())
988        })
989    }
990
991    /// Creates a callable value from a function.
992    ///
993    /// ```
994    /// # use minijinja::value::Value;
995    /// let pow = Value::from_function(|a: u32| a * a);
996    /// ```
997    pub fn from_function<F, Rv, Args>(f: F) -> Value
998    where
999        // the crazy bounds here exist to enable borrowing in closures
1000        F: functions::Function<Rv, Args>
1001            + for<'a> functions::Function<Rv, <Args as FunctionArgs<'a>>::Output>,
1002        Rv: FunctionResult,
1003        Args: for<'a> FunctionArgs<'a>,
1004    {
1005        functions::BoxedFunction::new(f).to_value()
1006    }
1007
1008    /// Returns the kind of the value.
1009    ///
1010    /// This can be used to determine what's in the value before trying to
1011    /// perform operations on it.
1012    pub fn kind(&self) -> ValueKind {
1013        match self.0 {
1014            ValueRepr::Undefined => ValueKind::Undefined,
1015            ValueRepr::Bool(_) => ValueKind::Bool,
1016            ValueRepr::U64(_) | ValueRepr::I64(_) | ValueRepr::F64(_) => ValueKind::Number,
1017            ValueRepr::None => ValueKind::None,
1018            ValueRepr::I128(_) => ValueKind::Number,
1019            ValueRepr::String(..) | ValueRepr::SmallStr(_) => ValueKind::String,
1020            ValueRepr::Bytes(_) => ValueKind::Bytes,
1021            ValueRepr::U128(_) => ValueKind::Number,
1022            ValueRepr::Invalid(_) => ValueKind::Invalid,
1023            ValueRepr::Object(ref obj) => match obj.repr() {
1024                ObjectRepr::Map => ValueKind::Map,
1025                ObjectRepr::Seq => ValueKind::Seq,
1026                ObjectRepr::Iterable => ValueKind::Iterable,
1027                ObjectRepr::Plain => ValueKind::Plain,
1028            },
1029        }
1030    }
1031
1032    /// Returns `true` if the value is a number.
1033    ///
1034    /// To convert a value into a primitive number, use [`TryFrom`] or [`TryInto`].
1035    pub fn is_number(&self) -> bool {
1036        matches!(
1037            self.0,
1038            ValueRepr::U64(_)
1039                | ValueRepr::I64(_)
1040                | ValueRepr::F64(_)
1041                | ValueRepr::I128(_)
1042                | ValueRepr::U128(_)
1043        )
1044    }
1045
1046    /// Returns true if the number is a real integer.
1047    ///
1048    /// This can be used to distinguish `42` from `42.0`.  For the most part
1049    /// the engine keeps these the same.
1050    pub fn is_integer(&self) -> bool {
1051        matches!(
1052            self.0,
1053            ValueRepr::U64(_) | ValueRepr::I64(_) | ValueRepr::I128(_) | ValueRepr::U128(_)
1054        )
1055    }
1056
1057    /// Returns `true` if the map represents keyword arguments.
1058    pub fn is_kwargs(&self) -> bool {
1059        Kwargs::extract(self).is_some()
1060    }
1061
1062    /// Is this value considered true?
1063    ///
1064    /// The engine inherits the same behavior as Jinja2 when it comes to
1065    /// considering objects true.  Empty objects are generally not considered
1066    /// true.  For custom objects this is customized by [`Object::is_true`].
1067    pub fn is_true(&self) -> bool {
1068        match self.0 {
1069            ValueRepr::Bool(val) => val,
1070            ValueRepr::U64(x) => x != 0,
1071            ValueRepr::U128(x) => x.0 != 0,
1072            ValueRepr::I64(x) => x != 0,
1073            ValueRepr::I128(x) => x.0 != 0,
1074            ValueRepr::F64(x) => x != 0.0,
1075            ValueRepr::String(ref x, _) => !x.is_empty(),
1076            ValueRepr::SmallStr(ref x) => !x.is_empty(),
1077            ValueRepr::Bytes(ref x) => !x.is_empty(),
1078            ValueRepr::None | ValueRepr::Undefined | ValueRepr::Invalid(_) => false,
1079            ValueRepr::Object(ref x) => x.is_true(),
1080        }
1081    }
1082
1083    /// Returns `true` if this value is safe.
1084    pub fn is_safe(&self) -> bool {
1085        matches!(&self.0, ValueRepr::String(_, StringType::Safe))
1086    }
1087
1088    /// Returns `true` if this value is undefined.
1089    pub fn is_undefined(&self) -> bool {
1090        matches!(&self.0, ValueRepr::Undefined)
1091    }
1092
1093    /// Returns `true` if this value is none.
1094    pub fn is_none(&self) -> bool {
1095        matches!(&self.0, ValueRepr::None)
1096    }
1097
1098    /// If the value is a string, return it.
1099    ///
1100    /// This will also perform a lossy string conversion of bytes from utf-8.
1101    pub fn to_str(&self) -> Option<Arc<str>> {
1102        match &self.0 {
1103            ValueRepr::String(ref s, _) => Some(s.clone()),
1104            ValueRepr::SmallStr(ref s) => Some(Arc::from(s.as_str())),
1105            ValueRepr::Bytes(ref b) => Some(Arc::from(String::from_utf8_lossy(b))),
1106            _ => None,
1107        }
1108    }
1109
1110    /// If the value is a string, return it.
1111    ///
1112    /// This will also return well formed utf-8 bytes as string.
1113    pub fn as_str(&self) -> Option<&str> {
1114        match &self.0 {
1115            ValueRepr::String(ref s, _) => Some(s as &str),
1116            ValueRepr::SmallStr(ref s) => Some(s.as_str()),
1117            ValueRepr::Bytes(ref b) => str::from_utf8(b).ok(),
1118            _ => None,
1119        }
1120    }
1121
1122    /// If this is an i64 return it
1123    pub fn as_usize(&self) -> Option<usize> {
1124        usize::try_from(self.clone()).ok()
1125    }
1126
1127    /// If this is an i64 return it
1128    pub fn as_i64(&self) -> Option<i64> {
1129        i64::try_from(self.clone()).ok()
1130    }
1131
1132    /// Returns the bytes of this value if they exist.
1133    pub fn as_bytes(&self) -> Option<&[u8]> {
1134        match &self.0 {
1135            ValueRepr::String(ref s, _) => Some(s.as_bytes()),
1136            ValueRepr::SmallStr(ref s) => Some(s.as_str().as_bytes()),
1137            ValueRepr::Bytes(ref b) => Some(&b[..]),
1138            _ => None,
1139        }
1140    }
1141
1142    /// If the value is an object a reference to it is returned.
1143    ///
1144    /// The returned value is a reference to a type erased [`DynObject`].
1145    /// For a specific type use [`downcast_object`](Self::downcast_object)
1146    /// instead.
1147    pub fn as_object(&self) -> Option<&DynObject> {
1148        match self.0 {
1149            ValueRepr::Object(ref dy) => Some(dy),
1150            _ => None,
1151        }
1152    }
1153
1154    /// Returns the length of the contained value.
1155    ///
1156    /// Values without a length will return `None`.
1157    ///
1158    /// ```
1159    /// # use minijinja::value::Value;
1160    /// let seq = Value::from(vec![1, 2, 3, 4]);
1161    /// assert_eq!(seq.len(), Some(4));
1162    /// ```
1163    pub fn len(&self) -> Option<usize> {
1164        match self.0 {
1165            ValueRepr::String(ref s, _) => Some(s.chars().count()),
1166            ValueRepr::SmallStr(ref s) => Some(s.as_str().chars().count()),
1167            ValueRepr::Bytes(ref b) => Some(b.len()),
1168            ValueRepr::Object(ref dy) => dy.enumerator_len(),
1169            _ => None,
1170        }
1171    }
1172
1173    /// Looks up an attribute by attribute name.
1174    ///
1175    /// This this returns [`UNDEFINED`](Self::UNDEFINED) when an invalid key is
1176    /// resolved.  An error is returned if the value does not contain an object
1177    /// that has attributes.
1178    ///
1179    /// ```
1180    /// # use minijinja::value::Value;
1181    /// # fn test() -> Result<(), minijinja::Error> {
1182    /// let ctx = minijinja::context! {
1183    ///     foo => "Foo"
1184    /// };
1185    /// let value = ctx.get_attr("foo")?;
1186    /// assert_eq!(value.to_string(), "Foo");
1187    /// # Ok(()) }
1188    /// ```
1189    pub fn get_attr(&self, key: &str) -> Result<Value, Error> {
1190        let value = match self.0 {
1191            ValueRepr::Undefined => return Err(Error::from(ErrorKind::UndefinedError)),
1192            ValueRepr::Object(ref dy) => dy.get_value(&Value::from(key)),
1193            _ => None,
1194        };
1195
1196        Ok(value.unwrap_or(Value::UNDEFINED))
1197    }
1198
1199    /// Alternative lookup strategy without error handling exclusively for context
1200    /// resolution.
1201    ///
1202    /// The main difference is that the return value will be `None` if the value is
1203    /// unable to look up the key rather than returning `Undefined` and errors will
1204    /// also not be created.
1205    pub(crate) fn get_attr_fast(&self, key: &str) -> Option<Value> {
1206        match self.0 {
1207            ValueRepr::Object(ref dy) => dy.get_value(&Value::from(key)),
1208            _ => None,
1209        }
1210    }
1211
1212    /// Looks up an index of the value.
1213    ///
1214    /// This is a shortcut for [`get_item`](Self::get_item).
1215    ///
1216    /// ```
1217    /// # use minijinja::value::Value;
1218    /// let seq = Value::from(vec![0u32, 1, 2]);
1219    /// let value = seq.get_item_by_index(1).unwrap();
1220    /// assert_eq!(value.try_into().ok(), Some(1));
1221    /// ```
1222    pub fn get_item_by_index(&self, idx: usize) -> Result<Value, Error> {
1223        self.get_item(&Value(ValueRepr::U64(idx as _)))
1224    }
1225
1226    /// Looks up an item (or attribute) by key.
1227    ///
1228    /// This is similar to [`get_attr`](Self::get_attr) but instead of using
1229    /// a string key this can be any key.  For instance this can be used to
1230    /// index into sequences.  Like [`get_attr`](Self::get_attr) this returns
1231    /// [`UNDEFINED`](Self::UNDEFINED) when an invalid key is looked up.
1232    ///
1233    /// ```
1234    /// # use minijinja::value::Value;
1235    /// let ctx = minijinja::context! {
1236    ///     foo => "Foo",
1237    /// };
1238    /// let value = ctx.get_item(&Value::from("foo")).unwrap();
1239    /// assert_eq!(value.to_string(), "Foo");
1240    /// ```
1241    pub fn get_item(&self, key: &Value) -> Result<Value, Error> {
1242        if let ValueRepr::Undefined = self.0 {
1243            Err(Error::from(ErrorKind::UndefinedError))
1244        } else {
1245            Ok(self.get_item_opt(key).unwrap_or(Value::UNDEFINED))
1246        }
1247    }
1248
1249    /// Iterates over the value.
1250    ///
1251    /// Depending on the [`kind`](Self::kind) of the value the iterator
1252    /// has a different behavior.
1253    ///
1254    /// * [`ValueKind::Map`]: the iterator yields the keys of the map.
1255    /// * [`ValueKind::Seq`] / [`ValueKind::Iterable`]: the iterator yields the items in the sequence.
1256    /// * [`ValueKind::String`]: the iterator yields characters in a string.
1257    /// * [`ValueKind::None`] / [`ValueKind::Undefined`]: the iterator is empty.
1258    ///
1259    /// ```
1260    /// # use minijinja::value::Value;
1261    /// # fn test() -> Result<(), minijinja::Error> {
1262    /// let value = Value::from({
1263    ///     let mut m = std::collections::BTreeMap::new();
1264    ///     m.insert("foo", 42);
1265    ///     m.insert("bar", 23);
1266    ///     m
1267    /// });
1268    /// for key in value.try_iter()? {
1269    ///     let value = value.get_item(&key)?;
1270    ///     println!("{} = {}", key, value);
1271    /// }
1272    /// # Ok(()) }
1273    /// ```
1274    pub fn try_iter(&self) -> Result<ValueIter, Error> {
1275        match self.0 {
1276            ValueRepr::None | ValueRepr::Undefined => Some(ValueIterImpl::Empty),
1277            ValueRepr::String(ref s, _) => {
1278                Some(ValueIterImpl::Chars(0, s.chars().count(), Arc::clone(s)))
1279            }
1280            ValueRepr::SmallStr(ref s) => Some(ValueIterImpl::Chars(
1281                0,
1282                s.as_str().chars().count(),
1283                Arc::from(s.as_str()),
1284            )),
1285            ValueRepr::Object(ref obj) => obj.try_iter().map(ValueIterImpl::Dyn),
1286            _ => None,
1287        }
1288        .map(|imp| ValueIter { imp })
1289        .ok_or_else(|| {
1290            Error::new(
1291                ErrorKind::InvalidOperation,
1292                format!("{} is not iterable", self.kind()),
1293            )
1294        })
1295    }
1296
1297    /// Returns a reversed view of this value.
1298    ///
1299    /// This is implemented for the following types with the following behaviors:
1300    ///
1301    /// * undefined or none: value returned unchanged.
1302    /// * string and bytes: returns a reversed version of that value
1303    /// * iterables: returns a reversed version of the iterable.  If the iterable is not
1304    ///   reversable itself, it consumes it and then reverses it.
1305    pub fn reverse(&self) -> Result<Value, Error> {
1306        match self.0 {
1307            ValueRepr::Undefined | ValueRepr::None => Some(self.clone()),
1308            ValueRepr::String(ref s, _) => Some(Value::from(s.chars().rev().collect::<String>())),
1309            ValueRepr::SmallStr(ref s) => {
1310                // TODO: add small str optimization here
1311                Some(Value::from(s.as_str().chars().rev().collect::<String>()))
1312            }
1313            ValueRepr::Bytes(ref b) => Some(Value::from_bytes(
1314                b.iter().rev().copied().collect::<Vec<_>>(),
1315            )),
1316            ValueRepr::Object(ref o) => match o.enumerate() {
1317                Enumerator::NonEnumerable => None,
1318                Enumerator::Empty => Some(Value::make_iterable(|| None::<Value>.into_iter())),
1319                Enumerator::Seq(l) => {
1320                    let self_clone = o.clone();
1321                    Some(Value::make_iterable(move || {
1322                        let self_clone = self_clone.clone();
1323                        (0..l).rev().map(move |idx| {
1324                            self_clone.get_value(&Value::from(idx)).unwrap_or_default()
1325                        })
1326                    }))
1327                }
1328                Enumerator::Iter(iter) => {
1329                    let mut v = iter.collect::<Vec<_>>();
1330                    v.reverse();
1331                    Some(Value::make_object_iterable(v, move |v| {
1332                        Box::new(v.iter().cloned())
1333                    }))
1334                }
1335                Enumerator::RevIter(rev_iter) => {
1336                    let for_restart = self.clone();
1337                    let iter = Mutex::new(Some(rev_iter));
1338                    Some(Value::make_iterable(move || {
1339                        if let Some(iter) = iter.lock().unwrap().take() {
1340                            Box::new(iter) as Box<dyn Iterator<Item = Value> + Send + Sync>
1341                        } else {
1342                            match for_restart.reverse().and_then(|x| x.try_iter()) {
1343                                Ok(iterable) => Box::new(iterable)
1344                                    as Box<dyn Iterator<Item = Value> + Send + Sync>,
1345                                Err(err) => Box::new(Some(Value::from(err)).into_iter())
1346                                    as Box<dyn Iterator<Item = Value> + Send + Sync>,
1347                            }
1348                        }
1349                    }))
1350                }
1351                Enumerator::Str(s) => Some(Value::make_iterable(move || s.iter().rev().copied())),
1352                Enumerator::Values(mut v) => {
1353                    v.reverse();
1354                    Some(Value::make_object_iterable(v, move |v| {
1355                        Box::new(v.iter().cloned())
1356                    }))
1357                }
1358            },
1359            _ => None,
1360        }
1361        .ok_or_else(|| {
1362            Error::new(
1363                ErrorKind::InvalidOperation,
1364                format!("cannot reverse values of type {}", self.kind()),
1365            )
1366        })
1367    }
1368
1369    /// Returns some reference to the boxed object if it is of type `T`, or None if it isn’t.
1370    ///
1371    /// This is basically the "reverse" of [`from_object`](Self::from_object)
1372    /// and [`from_dyn_object`](Self::from_dyn_object). It's also a shortcut for
1373    /// [`downcast_ref`](DynObject::downcast_ref) on the return value of
1374    /// [`as_object`](Self::as_object).
1375    ///
1376    /// # Example
1377    ///
1378    /// ```rust
1379    /// # use minijinja::value::{Value, Object};
1380    /// use std::fmt;
1381    ///
1382    /// #[derive(Debug)]
1383    /// struct Thing {
1384    ///     id: usize,
1385    /// }
1386    ///
1387    /// impl Object for Thing {}
1388    ///
1389    /// let x_value = Value::from_object(Thing { id: 42 });
1390    /// let thing = x_value.downcast_object_ref::<Thing>().unwrap();
1391    /// assert_eq!(thing.id, 42);
1392    /// ```
1393    pub fn downcast_object_ref<T: 'static>(&self) -> Option<&T> {
1394        match self.0 {
1395            ValueRepr::Object(ref o) => o.downcast_ref(),
1396            _ => None,
1397        }
1398    }
1399
1400    /// Like [`downcast_object_ref`](Self::downcast_object_ref) but returns
1401    /// the actual object.
1402    pub fn downcast_object<T: 'static>(&self) -> Option<Arc<T>> {
1403        match self.0 {
1404            ValueRepr::Object(ref o) => o.downcast(),
1405            _ => None,
1406        }
1407    }
1408
1409    pub(crate) fn get_item_opt(&self, key: &Value) -> Option<Value> {
1410        fn index(value: &Value, len: impl Fn() -> Option<usize>) -> Option<usize> {
1411            match value.as_i64().and_then(|v| isize::try_from(v).ok()) {
1412                Some(i) if i < 0 => some!(len()).checked_sub(i.unsigned_abs()),
1413                Some(i) => Some(i as usize),
1414                None => None,
1415            }
1416        }
1417
1418        match self.0 {
1419            ValueRepr::Object(ref dy) => match dy.repr() {
1420                ObjectRepr::Map | ObjectRepr::Plain => dy.get_value(key),
1421                ObjectRepr::Iterable => {
1422                    if let Some(rv) = dy.get_value(key) {
1423                        return Some(rv);
1424                    }
1425                    // The default behavior is to try to index into the iterable
1426                    // as if nth() was called.  This lets one slice an array and
1427                    // then index into it.
1428                    if let Some(idx) = index(key, || dy.enumerator_len()) {
1429                        if let Some(mut iter) = dy.try_iter() {
1430                            if let Some(rv) = iter.nth(idx) {
1431                                return Some(rv);
1432                            }
1433                        }
1434                    }
1435                    None
1436                }
1437                ObjectRepr::Seq => {
1438                    let idx = index(key, || dy.enumerator_len()).map(Value::from);
1439                    dy.get_value(idx.as_ref().unwrap_or(key))
1440                }
1441            },
1442            ValueRepr::String(ref s, _) => {
1443                let idx = some!(index(key, || Some(s.chars().count())));
1444                s.chars().nth(idx).map(Value::from)
1445            }
1446            ValueRepr::SmallStr(ref s) => {
1447                let idx = some!(index(key, || Some(s.as_str().chars().count())));
1448                s.as_str().chars().nth(idx).map(Value::from)
1449            }
1450            ValueRepr::Bytes(ref b) => {
1451                let idx = some!(index(key, || Some(b.len())));
1452                b.get(idx).copied().map(Value::from)
1453            }
1454            _ => None,
1455        }
1456    }
1457
1458    /// Calls the value directly.
1459    ///
1460    /// If the value holds a function or macro, this invokes it.  Note that in
1461    /// MiniJinja there is a separate namespace for methods on objects and callable
1462    /// items.  To call methods (which should be a rather rare occurrence) you
1463    /// have to use [`call_method`](Self::call_method).
1464    ///
1465    /// The `args` slice is for the arguments of the function call.  To pass
1466    /// keyword arguments use the [`Kwargs`] type.
1467    ///
1468    /// Usually the state is already available when it's useful to call this method,
1469    /// but when it's not available you can get a fresh template state straight
1470    /// from the [`Template`](crate::Template) via [`new_state`](crate::Template::new_state).
1471    ///
1472    /// ```
1473    /// # use minijinja::{Environment, value::{Value, Kwargs}};
1474    /// # let mut env = Environment::new();
1475    /// # env.add_template("foo", "").unwrap();
1476    /// # let tmpl = env.get_template("foo").unwrap();
1477    /// # let state = tmpl.new_state(); let state = &state;
1478    /// let func = Value::from_function(|v: i64, kwargs: Kwargs| {
1479    ///     v * kwargs.get::<i64>("mult").unwrap_or(1)
1480    /// });
1481    /// let rv = func.call(
1482    ///     state,
1483    ///     &[
1484    ///         Value::from(42),
1485    ///         Value::from(Kwargs::from_iter([("mult", Value::from(2))])),
1486    ///     ],
1487    /// ).unwrap();
1488    /// assert_eq!(rv, Value::from(84));
1489    /// ```
1490    ///
1491    /// With the [`args!`](crate::args) macro creating an argument slice is
1492    /// simplified:
1493    ///
1494    /// ```
1495    /// # use minijinja::{Environment, args, value::{Value, Kwargs}};
1496    /// # let mut env = Environment::new();
1497    /// # env.add_template("foo", "").unwrap();
1498    /// # let tmpl = env.get_template("foo").unwrap();
1499    /// # let state = tmpl.new_state(); let state = &state;
1500    /// let func = Value::from_function(|v: i64, kwargs: Kwargs| {
1501    ///     v * kwargs.get::<i64>("mult").unwrap_or(1)
1502    /// });
1503    /// let rv = func.call(state, args!(42, mult => 2)).unwrap();
1504    /// assert_eq!(rv, Value::from(84));
1505    /// ```
1506    pub fn call(&self, state: &State, args: &[Value]) -> Result<Value, Error> {
1507        if let ValueRepr::Object(ref dy) = self.0 {
1508            dy.call(state, args)
1509        } else {
1510            Err(Error::new(
1511                ErrorKind::InvalidOperation,
1512                format!("value of type {} is not callable", self.kind()),
1513            ))
1514        }
1515    }
1516
1517    /// Calls a method on the value.
1518    ///
1519    /// The name of the method is `name`, the arguments passed are in the `args`
1520    /// slice.
1521    pub fn call_method(&self, state: &State, name: &str, args: &[Value]) -> Result<Value, Error> {
1522        match self._call_method(state, name, args) {
1523            Ok(rv) => Ok(rv),
1524            Err(mut err) => {
1525                if err.kind() == ErrorKind::UnknownMethod {
1526                    if let Some(ref callback) = state.env().unknown_method_callback {
1527                        return callback(state, self, name, args);
1528                    } else if err.detail().is_none() {
1529                        err.set_detail(format!("{} has no method named {}", self.kind(), name));
1530                    }
1531                }
1532                Err(err)
1533            }
1534        }
1535    }
1536
1537    fn _call_method(&self, state: &State, name: &str, args: &[Value]) -> Result<Value, Error> {
1538        if let Some(object) = self.as_object() {
1539            object.call_method(state, name, args)
1540        } else {
1541            Err(Error::from(ErrorKind::UnknownMethod))
1542        }
1543    }
1544
1545    #[cfg(feature = "builtins")]
1546    pub(crate) fn get_path(&self, path: &str) -> Result<Value, Error> {
1547        let mut rv = self.clone();
1548        for part in path.split('.') {
1549            if let Ok(num) = part.parse::<usize>() {
1550                rv = ok!(rv.get_item_by_index(num));
1551            } else {
1552                rv = ok!(rv.get_attr(part));
1553            }
1554        }
1555        Ok(rv)
1556    }
1557
1558    #[cfg(feature = "builtins")]
1559    pub(crate) fn get_path_or_default(&self, path: &str, default: &Value) -> Value {
1560        match self.get_path(path) {
1561            Err(_) => default.clone(),
1562            Ok(val) if val.is_undefined() => default.clone(),
1563            Ok(val) => val,
1564        }
1565    }
1566}
1567
1568impl Serialize for Value {
1569    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1570    where
1571        S: Serializer,
1572    {
1573        // enable round tripping of values
1574        if serializing_for_value() {
1575            let handle = LAST_VALUE_HANDLE.with(|x| {
1576                // we are okay with overflowing the handle here because these values only
1577                // live for a very short period of time and it's not likely that you run out
1578                // of an entire u32 worth of handles in a single serialization operation.
1579                // This lets us stick the handle into a unit variant in the serde data model.
1580                let rv = x.get().wrapping_add(1);
1581                x.set(rv);
1582                rv
1583            });
1584            VALUE_HANDLES.with(|handles| handles.borrow_mut().insert(handle, self.clone()));
1585            return serializer.serialize_unit_variant(
1586                VALUE_HANDLE_MARKER,
1587                handle,
1588                VALUE_HANDLE_MARKER,
1589            );
1590        }
1591
1592        match self.0 {
1593            ValueRepr::Bool(b) => serializer.serialize_bool(b),
1594            ValueRepr::U64(u) => serializer.serialize_u64(u),
1595            ValueRepr::I64(i) => serializer.serialize_i64(i),
1596            ValueRepr::F64(f) => serializer.serialize_f64(f),
1597            ValueRepr::None | ValueRepr::Undefined | ValueRepr::Invalid(_) => {
1598                serializer.serialize_unit()
1599            }
1600            ValueRepr::U128(u) => serializer.serialize_u128(u.0),
1601            ValueRepr::I128(i) => serializer.serialize_i128(i.0),
1602            ValueRepr::String(ref s, _) => serializer.serialize_str(s),
1603            ValueRepr::SmallStr(ref s) => serializer.serialize_str(s.as_str()),
1604            ValueRepr::Bytes(ref b) => serializer.serialize_bytes(b),
1605            ValueRepr::Object(ref o) => match o.repr() {
1606                ObjectRepr::Plain => serializer.serialize_str(&o.to_string()),
1607                ObjectRepr::Seq | ObjectRepr::Iterable => {
1608                    use serde::ser::SerializeSeq;
1609                    let mut seq = ok!(serializer.serialize_seq(o.enumerator_len()));
1610                    if let Some(iter) = o.try_iter() {
1611                        for item in iter {
1612                            ok!(seq.serialize_element(&item));
1613                        }
1614                    }
1615
1616                    seq.end()
1617                }
1618                ObjectRepr::Map => {
1619                    use serde::ser::SerializeMap;
1620                    let mut map = ok!(serializer.serialize_map(None));
1621                    if let Some(iter) = o.try_iter_pairs() {
1622                        for (key, value) in iter {
1623                            ok!(map.serialize_entry(&key, &value));
1624                        }
1625                    }
1626
1627                    map.end()
1628                }
1629            },
1630        }
1631    }
1632}
1633
1634/// Utility to iterate over values.
1635pub struct ValueIter {
1636    imp: ValueIterImpl,
1637}
1638
1639impl Iterator for ValueIter {
1640    type Item = Value;
1641
1642    fn next(&mut self) -> Option<Self::Item> {
1643        match &mut self.imp {
1644            ValueIterImpl::Empty => None,
1645            ValueIterImpl::Chars(offset, len, ref s) => {
1646                (s as &str)[*offset..].chars().next().map(|c| {
1647                    *offset += c.len_utf8();
1648                    *len -= 1;
1649                    Value::from(c)
1650                })
1651            }
1652            ValueIterImpl::Dyn(iter) => iter.next(),
1653        }
1654    }
1655
1656    fn size_hint(&self) -> (usize, Option<usize>) {
1657        match self.imp {
1658            ValueIterImpl::Empty => (0, Some(0)),
1659            ValueIterImpl::Chars(_, len, _) => (0, Some(len)),
1660            ValueIterImpl::Dyn(ref iter) => iter.size_hint(),
1661        }
1662    }
1663}
1664
1665impl fmt::Debug for ValueIter {
1666    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1667        f.debug_struct("ValueIterator").finish()
1668    }
1669}
1670
1671enum ValueIterImpl {
1672    Empty,
1673    Chars(usize, usize, Arc<str>),
1674    Dyn(Box<dyn Iterator<Item = Value> + Send + Sync>),
1675}
1676
1677impl From<Error> for Value {
1678    fn from(value: Error) -> Self {
1679        Value(ValueRepr::Invalid(Arc::new(value)))
1680    }
1681}
1682
1683#[cfg(test)]
1684mod tests {
1685    use super::*;
1686
1687    use similar_asserts::assert_eq;
1688
1689    #[test]
1690    fn test_dynamic_object_roundtrip() {
1691        use std::sync::atomic::{self, AtomicUsize};
1692
1693        #[derive(Debug, Clone)]
1694        struct X(Arc<AtomicUsize>);
1695
1696        impl Object for X {
1697            fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
1698                match key.as_str()? {
1699                    "value" => Some(Value::from(self.0.load(atomic::Ordering::Relaxed))),
1700                    _ => None,
1701                }
1702            }
1703
1704            fn enumerate(self: &Arc<Self>) -> Enumerator {
1705                Enumerator::Str(&["value"])
1706            }
1707
1708            fn render(self: &Arc<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1709                write!(f, "{}", self.0.load(atomic::Ordering::Relaxed))
1710            }
1711        }
1712
1713        let x = Arc::new(X(Default::default()));
1714        let x_value = Value::from_dyn_object(x.clone());
1715        x.0.fetch_add(42, atomic::Ordering::Relaxed);
1716        let x_clone = Value::from_serialize(&x_value);
1717        x.0.fetch_add(23, atomic::Ordering::Relaxed);
1718
1719        assert_eq!(x_value.to_string(), "65");
1720        assert_eq!(x_clone.to_string(), "65");
1721    }
1722
1723    #[test]
1724    fn test_string_char() {
1725        let val = Value::from('a');
1726        assert_eq!(char::try_from(val).unwrap(), 'a');
1727        let val = Value::from("a");
1728        assert_eq!(char::try_from(val).unwrap(), 'a');
1729        let val = Value::from("wat");
1730        assert!(char::try_from(val).is_err());
1731    }
1732
1733    #[test]
1734    #[cfg(target_pointer_width = "64")]
1735    fn test_sizes() {
1736        assert_eq!(std::mem::size_of::<Value>(), 24);
1737    }
1738}