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, SerializeTupleStruct, 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::merge_object::merge_maps;
221pub use crate::value::object::{DynObject, Enumerator, Object, ObjectExt, ObjectRepr};
222
223#[macro_use]
224mod type_erase;
225mod argtypes;
226#[cfg(feature = "deserialization")]
227mod deserialize;
228pub(crate) mod merge_object;
229pub(crate) mod namespace_object;
230mod object;
231pub(crate) mod ops;
232mod serialize;
233
234#[cfg(feature = "deserialization")]
235pub use self::deserialize::ViaDeserialize;
236
237// We use in-band signalling to roundtrip some internal values.  This is
238// not ideal but unfortunately there is no better system in serde today.
239const VALUE_HANDLE_MARKER: &str = "\x01__minijinja_ValueHandle";
240
241#[cfg(feature = "preserve_order")]
242pub(crate) type ValueMap = indexmap::IndexMap<Value, Value>;
243
244#[cfg(not(feature = "preserve_order"))]
245pub(crate) type ValueMap = std::collections::BTreeMap<Value, Value>;
246
247#[inline(always)]
248pub(crate) fn value_map_with_capacity(capacity: usize) -> ValueMap {
249    #[cfg(not(feature = "preserve_order"))]
250    {
251        let _ = capacity;
252        ValueMap::new()
253    }
254    #[cfg(feature = "preserve_order")]
255    {
256        ValueMap::with_capacity(crate::utils::untrusted_size_hint(capacity))
257    }
258}
259
260thread_local! {
261    static INTERNAL_SERIALIZATION: Cell<bool> = const { Cell::new(false) };
262
263    // This should be an AtomicU64 but sadly 32bit targets do not necessarily have
264    // AtomicU64 available.
265    static LAST_VALUE_HANDLE: Cell<u32> = const { Cell::new(0) };
266    static VALUE_HANDLES: RefCell<BTreeMap<u32, Value>> = const { RefCell::new(BTreeMap::new()) };
267}
268
269/// Function that returns true when serialization for [`Value`] is taking place.
270///
271/// MiniJinja internally creates [`Value`] objects from all values passed to the
272/// engine.  It does this by going through the regular serde serialization trait.
273/// In some cases users might want to customize the serialization specifically for
274/// MiniJinja because they want to tune the object for the template engine
275/// independently of what is normally serialized to disk.
276///
277/// This function returns `true` when MiniJinja is serializing to [`Value`] and
278/// `false` otherwise.  You can call this within your own [`Serialize`]
279/// implementation to change the output format.
280///
281/// This is particularly useful as serialization for MiniJinja does not need to
282/// support deserialization.  So it becomes possible to completely change what
283/// gets sent there, even at the cost of serializing something that cannot be
284/// deserialized.
285pub fn serializing_for_value() -> bool {
286    INTERNAL_SERIALIZATION.with(|flag| flag.get())
287}
288
289fn mark_internal_serialization() -> impl Drop {
290    let old = INTERNAL_SERIALIZATION.with(|flag| {
291        let old = flag.get();
292        flag.set(true);
293        old
294    });
295    OnDrop::new(move || {
296        if !old {
297            INTERNAL_SERIALIZATION.with(|flag| flag.set(false));
298        }
299    })
300}
301
302/// Describes the kind of value.
303#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
304#[non_exhaustive]
305pub enum ValueKind {
306    /// The value is undefined
307    Undefined,
308    /// The value is the none singleton (`()`)
309    None,
310    /// The value is a [`bool`]
311    Bool,
312    /// The value is a number of a supported type.
313    Number,
314    /// The value is a string.
315    String,
316    /// The value is a byte array.
317    Bytes,
318    /// The value is an array of other values.
319    Seq,
320    /// The value is a key/value mapping.
321    Map,
322    /// An iterable
323    Iterable,
324    /// A plain object without specific behavior.
325    Plain,
326    /// This value is invalid (holds an error).
327    ///
328    /// This can happen when a serialization error occurred or the engine
329    /// encountered a failure in a place where an error can otherwise not
330    /// be produced.  Interacting with such values in the context of the
331    /// template evaluation process will attempt to propagate the error.
332    Invalid,
333}
334
335impl fmt::Display for ValueKind {
336    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
337        f.write_str(match *self {
338            ValueKind::Undefined => "undefined",
339            ValueKind::None => "none",
340            ValueKind::Bool => "bool",
341            ValueKind::Number => "number",
342            ValueKind::String => "string",
343            ValueKind::Bytes => "bytes",
344            ValueKind::Seq => "sequence",
345            ValueKind::Map => "map",
346            ValueKind::Iterable => "iterator",
347            ValueKind::Plain => "plain object",
348            ValueKind::Invalid => "invalid value",
349        })
350    }
351}
352
353/// Type type of string
354#[derive(Copy, Clone, Debug)]
355pub(crate) enum StringType {
356    Normal,
357    Safe,
358}
359
360/// Type type of undefined
361#[derive(Copy, Clone, Debug)]
362pub(crate) enum UndefinedType {
363    Default,
364    Silent,
365}
366
367/// Wraps an internal copyable value but marks it as packed.
368///
369/// This is used for `i128`/`u128` in the value repr to avoid
370/// the excessive 16 byte alignment.
371#[derive(Copy, Debug)]
372#[cfg_attr(feature = "unstable_machinery_serde", derive(serde::Serialize))]
373#[repr(packed)]
374pub(crate) struct Packed<T: Copy>(pub T);
375
376impl<T: Copy> Clone for Packed<T> {
377    fn clone(&self) -> Self {
378        *self
379    }
380}
381
382/// Max size of a small str.
383///
384/// Logic: Value is 24 bytes. 1 byte is for the discriminant. One byte is
385/// needed for the small str length.
386const SMALL_STR_CAP: usize = 22;
387
388/// Helper to store string data inline.
389#[derive(Clone)]
390pub(crate) struct SmallStr {
391    len: u8,
392    buf: [u8; SMALL_STR_CAP],
393}
394
395impl SmallStr {
396    pub fn try_new(s: &str) -> Option<SmallStr> {
397        let len = s.len();
398        if len <= SMALL_STR_CAP {
399            let mut buf = [0u8; SMALL_STR_CAP];
400            buf[..len].copy_from_slice(s.as_bytes());
401            Some(SmallStr {
402                len: len as u8,
403                buf,
404            })
405        } else {
406            None
407        }
408    }
409
410    pub fn as_str(&self) -> &str {
411        // SAFETY: This is safe because we only place well-formed utf-8 strings
412        unsafe { std::str::from_utf8_unchecked(&self.buf[..self.len as usize]) }
413    }
414
415    pub fn is_empty(&self) -> bool {
416        self.len == 0
417    }
418}
419
420#[derive(Clone)]
421pub(crate) enum ValueRepr {
422    None,
423    Undefined(UndefinedType),
424    Bool(bool),
425    U64(u64),
426    I64(i64),
427    F64(f64),
428    Invalid(Arc<Error>),
429    U128(Packed<u128>),
430    I128(Packed<i128>),
431    String(Arc<str>, StringType),
432    SmallStr(SmallStr),
433    Bytes(Arc<Vec<u8>>),
434    Object(DynObject),
435}
436
437impl fmt::Debug for ValueRepr {
438    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
439        match *self {
440            ValueRepr::Undefined(_) => f.write_str("undefined"),
441            ValueRepr::Bool(ref val) => fmt::Debug::fmt(val, f),
442            ValueRepr::U64(ref val) => fmt::Debug::fmt(val, f),
443            ValueRepr::I64(ref val) => fmt::Debug::fmt(val, f),
444            ValueRepr::F64(ref val) => fmt::Debug::fmt(val, f),
445            ValueRepr::None => f.write_str("none"),
446            ValueRepr::Invalid(ref val) => write!(f, "<invalid value: {}>", val),
447            ValueRepr::U128(val) => fmt::Debug::fmt(&{ val.0 }, f),
448            ValueRepr::I128(val) => fmt::Debug::fmt(&{ val.0 }, f),
449            ValueRepr::String(ref val, _) => fmt::Debug::fmt(val, f),
450            ValueRepr::SmallStr(ref val) => fmt::Debug::fmt(val.as_str(), f),
451            ValueRepr::Bytes(ref val) => {
452                write!(f, "b'")?;
453                for &b in val.iter() {
454                    if b == b'"' {
455                        write!(f, "\"")?
456                    } else {
457                        write!(f, "{}", b.escape_ascii())?;
458                    }
459                }
460                write!(f, "'")
461            }
462            ValueRepr::Object(ref val) => val.render(f),
463        }
464    }
465}
466
467impl Hash for Value {
468    fn hash<H: Hasher>(&self, state: &mut H) {
469        match self.0 {
470            ValueRepr::None | ValueRepr::Undefined(_) => 0u8.hash(state),
471            ValueRepr::String(ref s, _) => s.hash(state),
472            ValueRepr::SmallStr(ref s) => s.as_str().hash(state),
473            ValueRepr::Bool(b) => b.hash(state),
474            ValueRepr::Invalid(ref e) => (e.kind(), e.detail()).hash(state),
475            ValueRepr::Bytes(ref b) => b.hash(state),
476            ValueRepr::Object(ref d) => d.hash(state),
477            ValueRepr::U64(_)
478            | ValueRepr::I64(_)
479            | ValueRepr::F64(_)
480            | ValueRepr::U128(_)
481            | ValueRepr::I128(_) => {
482                if let Ok(val) = i64::try_from(self.clone()) {
483                    val.hash(state)
484                } else {
485                    as_f64(self, true).map(|x| x.to_bits()).hash(state)
486                }
487            }
488        }
489    }
490}
491
492/// Represents a dynamically typed value in the template engine.
493#[derive(Clone)]
494pub struct Value(pub(crate) ValueRepr);
495
496impl PartialEq for Value {
497    fn eq(&self, other: &Self) -> bool {
498        match (&self.0, &other.0) {
499            (&ValueRepr::None, &ValueRepr::None) => true,
500            (&ValueRepr::Undefined(_), &ValueRepr::Undefined(_)) => true,
501            (&ValueRepr::String(ref a, _), &ValueRepr::String(ref b, _)) => a == b,
502            (&ValueRepr::SmallStr(ref a), &ValueRepr::SmallStr(ref b)) => a.as_str() == b.as_str(),
503            (&ValueRepr::Bytes(ref a), &ValueRepr::Bytes(ref b)) => a == b,
504            _ => match ops::coerce(self, other, false) {
505                Some(ops::CoerceResult::F64(a, b)) => a == b,
506                Some(ops::CoerceResult::I128(a, b)) => a == b,
507                Some(ops::CoerceResult::Str(a, b)) => a == b,
508                None => {
509                    if let (Some(a), Some(b)) = (self.as_object(), other.as_object()) {
510                        if a.is_same_object(b) {
511                            return true;
512                        } else if a.is_same_object_type(b) {
513                            if let Some(rv) = a.custom_cmp(b) {
514                                return rv == Ordering::Equal;
515                            }
516                        }
517                        match (a.repr(), b.repr()) {
518                            (ObjectRepr::Map, ObjectRepr::Map) => {
519                                // only if we have known lengths can we compare the enumerators
520                                // ahead of time.  This function has a fallback for when a
521                                // map has an unknown length.  That's generally a bad idea, but
522                                // it makes sense supporting regardless as silent failures are
523                                // not a lot of fun.
524                                let mut need_length_fallback = true;
525                                if let (Some(a_len), Some(b_len)) =
526                                    (a.enumerator_len(), b.enumerator_len())
527                                {
528                                    if a_len != b_len {
529                                        return false;
530                                    }
531                                    need_length_fallback = false;
532                                }
533                                let mut a_count = 0;
534                                if !a.try_iter_pairs().is_some_and(|mut ak| {
535                                    ak.all(|(k, v1)| {
536                                        a_count += 1;
537                                        b.get_value(&k) == Some(v1)
538                                    })
539                                }) {
540                                    return false;
541                                }
542                                if !need_length_fallback {
543                                    true
544                                } else {
545                                    a_count == b.try_iter().map_or(0, |x| x.count())
546                                }
547                            }
548                            (
549                                ObjectRepr::Seq | ObjectRepr::Iterable,
550                                ObjectRepr::Seq | ObjectRepr::Iterable,
551                            ) => {
552                                if let (Some(ak), Some(bk)) = (a.try_iter(), b.try_iter()) {
553                                    ak.eq(bk)
554                                } else {
555                                    false
556                                }
557                            }
558                            // terrible fallback for plain objects
559                            (ObjectRepr::Plain, ObjectRepr::Plain) => {
560                                a.to_string() == b.to_string()
561                            }
562                            // should not happen
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(ref a), &ValueRepr::SmallStr(ref b)) => {
602                a.as_str().cmp(b.as_str())
603            }
604            (&ValueRepr::Bytes(ref a), &ValueRepr::Bytes(ref b)) => a.cmp(b),
605            _ => match ops::coerce(self, other, false) {
606                Some(ops::CoerceResult::F64(a, b)) => f64_total_cmp(a, b),
607                Some(ops::CoerceResult::I128(a, b)) => a.cmp(&b),
608                Some(ops::CoerceResult::Str(a, b)) => a.cmp(b),
609                None => {
610                    let a = self.as_object().unwrap();
611                    let b = other.as_object().unwrap();
612
613                    if a.is_same_object(b) {
614                        Ordering::Equal
615                    } else {
616                        // if there is a custom comparison, run it.
617                        if a.is_same_object_type(b) {
618                            if let Some(rv) = a.custom_cmp(b) {
619                                return rv;
620                            }
621                        }
622                        match (a.repr(), b.repr()) {
623                            (ObjectRepr::Map, ObjectRepr::Map) => {
624                                // This is not really correct.  Because the keys can be in arbitrary
625                                // order this could just sort really weirdly as a result.  However
626                                // we don't want to pay the cost of actually sorting the keys for
627                                // ordering so we just accept this for now.
628                                match (a.try_iter_pairs(), b.try_iter_pairs()) {
629                                    (Some(a), Some(b)) => a.cmp(b),
630                                    _ => unreachable!(),
631                                }
632                            }
633                            (
634                                ObjectRepr::Seq | ObjectRepr::Iterable,
635                                ObjectRepr::Seq | ObjectRepr::Iterable,
636                            ) => match (a.try_iter(), b.try_iter()) {
637                                (Some(a), Some(b)) => a.cmp(b),
638                                _ => unreachable!(),
639                            },
640                            // terrible fallback for plain objects
641                            (ObjectRepr::Plain, ObjectRepr::Plain) => {
642                                a.to_string().cmp(&b.to_string())
643                            }
644                            // should not happen
645                            (_, _) => unreachable!(),
646                        }
647                    }
648                }
649            },
650        }
651    }
652}
653
654impl fmt::Debug for Value {
655    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
656        fmt::Debug::fmt(&self.0, f)
657    }
658}
659
660impl fmt::Display for Value {
661    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
662        match self.0 {
663            ValueRepr::Undefined(_) => Ok(()),
664            ValueRepr::Bool(val) => val.fmt(f),
665            ValueRepr::U64(val) => val.fmt(f),
666            ValueRepr::I64(val) => val.fmt(f),
667            ValueRepr::F64(val) => {
668                if val.is_nan() {
669                    f.write_str("NaN")
670                } else if val.is_infinite() {
671                    write!(f, "{}inf", if val.is_sign_negative() { "-" } else { "" })
672                } else {
673                    let mut num = val.to_string();
674                    if !num.contains('.') {
675                        num.push_str(".0");
676                    }
677                    write!(f, "{num}")
678                }
679            }
680            ValueRepr::None => f.write_str("none"),
681            ValueRepr::Invalid(ref val) => write!(f, "<invalid value: {}>", val),
682            ValueRepr::I128(val) => write!(f, "{}", { val.0 }),
683            ValueRepr::String(ref val, _) => write!(f, "{val}"),
684            ValueRepr::SmallStr(ref val) => write!(f, "{}", val.as_str()),
685            ValueRepr::Bytes(ref val) => write!(f, "{}", String::from_utf8_lossy(val)),
686            ValueRepr::U128(val) => write!(f, "{}", { val.0 }),
687            ValueRepr::Object(ref x) => write!(f, "{x}"),
688        }
689    }
690}
691
692impl Default for Value {
693    fn default() -> Value {
694        ValueRepr::Undefined(UndefinedType::Default).into()
695    }
696}
697
698#[doc(hidden)]
699#[deprecated = "This function no longer has an effect.  Use Arc::from directly."]
700pub fn intern(s: &str) -> Arc<str> {
701    Arc::from(s.to_string())
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(UndefinedType::Default));
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        transform(value)
743    }
744
745    /// Extracts a contained error.
746    ///
747    /// An invalid value carres an error internally and will reveal that error
748    /// at a later point when iteracted with.  This is used to carry
749    /// serialization errors or failures that happen when the engine otherwise
750    /// assumes an infallible operation such as iteration.
751    pub(crate) fn validate(self) -> Result<Value, Error> {
752        if let ValueRepr::Invalid(err) = self.0 {
753            // Today the API implies tghat errors are `Clone`, but we don't want to expose
754            // this as a functionality (yet?).
755            Err(Arc::try_unwrap(err).unwrap_or_else(|arc| (*arc).internal_clone()))
756        } else {
757            Ok(self)
758        }
759    }
760
761    /// Creates a value from a safe string.
762    ///
763    /// A safe string is one that will bypass auto escaping.  For instance if you
764    /// want to have the template engine render some HTML without the user having to
765    /// supply the `|safe` filter, you can use a value of this type instead.
766    ///
767    /// ```
768    /// # use minijinja::value::Value;
769    /// let val = Value::from_safe_string("<em>note</em>".into());
770    /// ```
771    pub fn from_safe_string(value: String) -> Value {
772        ValueRepr::String(Arc::from(value), StringType::Safe).into()
773    }
774
775    /// Creates a value from a byte vector.
776    ///
777    /// MiniJinja can hold on to bytes and has some limited built-in support for
778    /// working with them.  They are non iterable and not particularly useful
779    /// in the context of templates.  When they are stringified, they are assumed
780    /// to contain UTF-8 and will be treated as such.  They become more useful
781    /// when a filter can do something with them (eg: base64 encode them etc.).
782    ///
783    /// This method exists so that a value can be constructed as creating a
784    /// value from a `Vec<u8>` would normally just create a sequence.
785    pub fn from_bytes(value: Vec<u8>) -> Value {
786        ValueRepr::Bytes(value.into()).into()
787    }
788
789    /// Creates a value from a dynamic object.
790    ///
791    /// For more information see [`Object`].
792    ///
793    /// ```rust
794    /// # use minijinja::value::{Value, Object};
795    /// use std::fmt;
796    ///
797    /// #[derive(Debug)]
798    /// struct Thing {
799    ///     id: usize,
800    /// }
801    ///
802    /// impl Object for Thing {}
803    ///
804    /// let val = Value::from_object(Thing { id: 42 });
805    /// ```
806    pub fn from_object<T: Object + Send + Sync + 'static>(value: T) -> Value {
807        Value::from(ValueRepr::Object(DynObject::new(Arc::new(value))))
808    }
809
810    /// Like [`from_object`](Self::from_object) but for type erased dynamic objects.
811    ///
812    /// This especially useful if you have an object that has an `Arc<T>` to another
813    /// child object that you want to return as a `Arc<T>` turns into a [`DynObject`]
814    /// automatically.
815    ///
816    /// ```rust
817    /// # use std::sync::Arc;
818    /// # use minijinja::value::{Value, Object, Enumerator};
819    /// #[derive(Debug)]
820    /// pub struct HttpConfig {
821    ///     port: usize,
822    /// }
823    ///
824    /// #[derive(Debug)]
825    /// struct Config {
826    ///     http: Arc<HttpConfig>,
827    /// }
828    ///
829    /// impl Object for HttpConfig {
830    ///     fn enumerate(self: &Arc<Self>) -> Enumerator {
831    ///         Enumerator::Str(&["port"])
832    ///     }
833    ///
834    ///     fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
835    ///         match key.as_str()? {
836    ///             "port" => Some(Value::from(self.port)),
837    ///             _ => None,
838    ///         }
839    ///     }
840    /// }
841    ///
842    /// impl Object for Config {
843    ///     fn enumerate(self: &Arc<Self>) -> Enumerator {
844    ///         Enumerator::Str(&["http"])
845    ///     }
846    ///
847    ///     fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
848    ///         match key.as_str()? {
849    ///             "http" => Some(Value::from_dyn_object(self.http.clone())),
850    ///             _ => None
851    ///         }
852    ///     }
853    /// }
854    /// ```
855    pub fn from_dyn_object<T: Into<DynObject>>(value: T) -> Value {
856        Value::from(ValueRepr::Object(value.into()))
857    }
858
859    /// Creates a value that is an iterable.
860    ///
861    /// The function is invoked to create a new iterator every time the value is
862    /// iterated over.
863    ///
864    /// ```
865    /// # use minijinja::value::Value;
866    /// let val = Value::make_iterable(|| 0..10);
867    /// ```
868    ///
869    /// Iterators that implement [`ExactSizeIterator`] or have a matching lower and upper
870    /// bound on the [`Iterator::size_hint`] report a known `loop.length`.  Iterators that
871    /// do not fulfill these requirements will not.  The same is true for `revindex` and
872    /// similar properties.
873    pub fn make_iterable<I, T, F>(maker: F) -> Value
874    where
875        I: Iterator<Item = T> + Send + Sync + 'static,
876        T: Into<Value> + Send + Sync + 'static,
877        F: Fn() -> I + Send + Sync + 'static,
878    {
879        Value::make_object_iterable((), move |_| Box::new(maker().map(Into::into)))
880    }
881
882    /// Creates an iterable that iterates over the given value.
883    ///
884    /// This is similar to [`make_iterable`](Self::make_iterable) but it takes an extra
885    /// reference to a value it can borrow out from.  It's a bit less generic in that it
886    /// needs to return a boxed iterator of values directly.
887    ///
888    /// ```rust
889    /// # use minijinja::value::Value;
890    /// let val = Value::make_object_iterable(vec![1, 2, 3], |vec| {
891    ///     Box::new(vec.iter().copied().map(Value::from))
892    /// });
893    /// assert_eq!(val.to_string(), "[1, 2, 3]");
894    /// ````
895    pub fn make_object_iterable<T, F>(object: T, maker: F) -> Value
896    where
897        T: Send + Sync + 'static,
898        F: for<'a> Fn(&'a T) -> Box<dyn Iterator<Item = Value> + Send + Sync + 'a>
899            + Send
900            + Sync
901            + 'static,
902    {
903        struct Iterable<T, F> {
904            maker: F,
905            object: T,
906        }
907
908        impl<T, F> fmt::Debug for Iterable<T, F> {
909            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
910                f.debug_struct("<iterator>").finish()
911            }
912        }
913
914        impl<T, F> Object for Iterable<T, F>
915        where
916            T: Send + Sync + 'static,
917            F: for<'a> Fn(&'a T) -> Box<dyn Iterator<Item = Value> + Send + Sync + 'a>
918                + Send
919                + Sync
920                + 'static,
921        {
922            fn repr(self: &Arc<Self>) -> ObjectRepr {
923                ObjectRepr::Iterable
924            }
925
926            fn enumerate(self: &Arc<Self>) -> Enumerator {
927                mapped_enumerator(self, |this| (this.maker)(&this.object))
928            }
929        }
930
931        Value::from_object(Iterable { maker, object })
932    }
933
934    /// Creates an object projection onto a map.
935    ///
936    /// This is similar to [`make_object_iterable`](Self::make_object_iterable) but
937    /// it creates a map rather than an iterable.  To accomplish this, it also
938    /// requires two callbacks.  One for enumeration, and one for looking up
939    /// attributes.
940    ///
941    /// # Example
942    ///
943    /// ```
944    /// use std::collections::HashMap;
945    /// use std::sync::Arc;
946    /// use minijinja::value::{Value, Object, ObjectExt, Enumerator};
947    ///
948    /// #[derive(Debug)]
949    /// struct Element {
950    ///     tag: String,
951    ///     attrs: HashMap<String, String>,
952    /// }
953    ///
954    /// impl Object for Element {
955    ///     fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
956    ///         match key.as_str()? {
957    ///             "tag" => Some(Value::from(&self.tag)),
958    ///             "attrs" => Some(Value::make_object_map(
959    ///                 self.clone(),
960    ///                 |this| Box::new(this.attrs.keys().map(Value::from)),
961    ///                 |this, key| this.attrs.get(key.as_str()?).map(Value::from),
962    ///             )),
963    ///             _ => None
964    ///         }
965    ///     }
966    ///
967    ///     fn enumerate(self: &Arc<Self>) -> Enumerator {
968    ///         Enumerator::Str(&["tag", "attrs"])
969    ///     }
970    /// }
971    /// ```
972    pub fn make_object_map<T, E, A>(object: T, enumerate_fn: E, attr_fn: A) -> Value
973    where
974        T: Send + Sync + 'static,
975        E: for<'a> Fn(&'a T) -> Box<dyn Iterator<Item = Value> + Send + Sync + 'a>
976            + Send
977            + Sync
978            + 'static,
979        A: Fn(&T, &Value) -> Option<Value> + Send + Sync + 'static,
980    {
981        struct ProxyMapObject<T, E, A> {
982            enumerate_fn: E,
983            attr_fn: A,
984            object: T,
985        }
986
987        impl<T, E, A> fmt::Debug for ProxyMapObject<T, E, A> {
988            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
989                f.debug_struct("<map-object>").finish()
990            }
991        }
992
993        impl<T, E, A> Object for ProxyMapObject<T, E, A>
994        where
995            T: Send + Sync + 'static,
996            E: for<'a> Fn(&'a T) -> Box<dyn Iterator<Item = Value> + Send + Sync + 'a>
997                + Send
998                + Sync
999                + 'static,
1000            A: Fn(&T, &Value) -> Option<Value> + Send + Sync + 'static,
1001        {
1002            #[inline]
1003            fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
1004                (self.attr_fn)(&self.object, key)
1005            }
1006
1007            #[inline]
1008            fn enumerate(self: &Arc<Self>) -> Enumerator {
1009                mapped_enumerator(self, |this| (this.enumerate_fn)(&this.object))
1010            }
1011        }
1012
1013        Value::from_object(ProxyMapObject {
1014            enumerate_fn,
1015            attr_fn,
1016            object,
1017        })
1018    }
1019
1020    /// Creates a value from a one-shot iterator.
1021    ///
1022    /// This takes an iterator (yielding values that can be turned into a [`Value`])
1023    /// and wraps it in a way that it turns into an iterable value.  From the view of
1024    /// the template this can be iterated over exactly once for the most part once
1025    /// exhausted.
1026    ///
1027    /// Such iterators are strongly recommended against in the general sense due to
1028    /// their surprising behavior, but they can be useful for more advanced use
1029    /// cases where data should be streamed into the template as it becomes available.
1030    ///
1031    /// Such iterators never have any size hints.
1032    ///
1033    /// ```
1034    /// # use minijinja::value::Value;
1035    /// let val = Value::make_one_shot_iterator(0..10);
1036    /// ```
1037    ///
1038    /// Attempting to iterate over it a second time will not yield any more items.
1039    pub fn make_one_shot_iterator<I, T>(iter: I) -> Value
1040    where
1041        I: Iterator<Item = T> + Send + Sync + 'static,
1042        T: Into<Value> + Send + Sync + 'static,
1043    {
1044        let iter = Arc::new(Mutex::new(iter.fuse()));
1045        Value::make_iterable(move || {
1046            let iter = iter.clone();
1047            std::iter::from_fn(move || iter.lock().unwrap().next())
1048        })
1049    }
1050
1051    /// Creates a callable value from a function.
1052    ///
1053    /// ```
1054    /// # use minijinja::value::Value;
1055    /// let pow = Value::from_function(|a: u32| a * a);
1056    /// ```
1057    pub fn from_function<F, Rv, Args>(f: F) -> Value
1058    where
1059        F: functions::Function<Rv, Args>,
1060        Rv: FunctionResult,
1061        Args: for<'a> FunctionArgs<'a>,
1062    {
1063        functions::BoxedFunction::new(f).to_value()
1064    }
1065
1066    /// Returns the kind of the value.
1067    ///
1068    /// This can be used to determine what's in the value before trying to
1069    /// perform operations on it.
1070    pub fn kind(&self) -> ValueKind {
1071        match self.0 {
1072            ValueRepr::Undefined(_) => ValueKind::Undefined,
1073            ValueRepr::Bool(_) => ValueKind::Bool,
1074            ValueRepr::U64(_) | ValueRepr::I64(_) | ValueRepr::F64(_) => ValueKind::Number,
1075            ValueRepr::None => ValueKind::None,
1076            ValueRepr::I128(_) => ValueKind::Number,
1077            ValueRepr::String(..) | ValueRepr::SmallStr(_) => ValueKind::String,
1078            ValueRepr::Bytes(_) => ValueKind::Bytes,
1079            ValueRepr::U128(_) => ValueKind::Number,
1080            ValueRepr::Invalid(_) => ValueKind::Invalid,
1081            ValueRepr::Object(ref obj) => match obj.repr() {
1082                ObjectRepr::Map => ValueKind::Map,
1083                ObjectRepr::Seq => ValueKind::Seq,
1084                ObjectRepr::Iterable => ValueKind::Iterable,
1085                ObjectRepr::Plain => ValueKind::Plain,
1086            },
1087        }
1088    }
1089
1090    /// Returns `true` if the value is a number.
1091    ///
1092    /// To convert a value into a primitive number, use [`TryFrom`] or [`TryInto`].
1093    pub fn is_number(&self) -> bool {
1094        matches!(
1095            self.0,
1096            ValueRepr::U64(_)
1097                | ValueRepr::I64(_)
1098                | ValueRepr::F64(_)
1099                | ValueRepr::I128(_)
1100                | ValueRepr::U128(_)
1101        )
1102    }
1103
1104    /// Returns true if the number is a real integer.
1105    ///
1106    /// This can be used to distinguish `42` from `42.0`.  For the most part
1107    /// the engine keeps these the same.
1108    pub fn is_integer(&self) -> bool {
1109        matches!(
1110            self.0,
1111            ValueRepr::U64(_) | ValueRepr::I64(_) | ValueRepr::I128(_) | ValueRepr::U128(_)
1112        )
1113    }
1114
1115    /// Returns `true` if the map represents keyword arguments.
1116    pub fn is_kwargs(&self) -> bool {
1117        Kwargs::extract(self).is_some()
1118    }
1119
1120    /// Is this value considered true?
1121    ///
1122    /// The engine inherits the same behavior as Jinja2 when it comes to
1123    /// considering objects true.  Empty objects are generally not considered
1124    /// true.  For custom objects this is customized by [`Object::is_true`].
1125    pub fn is_true(&self) -> bool {
1126        match self.0 {
1127            ValueRepr::Bool(val) => val,
1128            ValueRepr::U64(x) => x != 0,
1129            ValueRepr::U128(x) => x.0 != 0,
1130            ValueRepr::I64(x) => x != 0,
1131            ValueRepr::I128(x) => x.0 != 0,
1132            ValueRepr::F64(x) => x != 0.0,
1133            ValueRepr::String(ref x, _) => !x.is_empty(),
1134            ValueRepr::SmallStr(ref x) => !x.is_empty(),
1135            ValueRepr::Bytes(ref x) => !x.is_empty(),
1136            ValueRepr::None | ValueRepr::Undefined(_) | ValueRepr::Invalid(_) => false,
1137            ValueRepr::Object(ref x) => x.is_true(),
1138        }
1139    }
1140
1141    /// Returns `true` if this value is safe.
1142    pub fn is_safe(&self) -> bool {
1143        matches!(&self.0, ValueRepr::String(_, StringType::Safe))
1144    }
1145
1146    /// Returns `true` if this value is undefined.
1147    pub fn is_undefined(&self) -> bool {
1148        matches!(&self.0, ValueRepr::Undefined(_))
1149    }
1150
1151    /// Returns `true` if this value is none.
1152    pub fn is_none(&self) -> bool {
1153        matches!(&self.0, ValueRepr::None)
1154    }
1155
1156    /// If the value is a string, return it.
1157    ///
1158    /// This will also perform a lossy string conversion of bytes from utf-8.
1159    pub fn to_str(&self) -> Option<Arc<str>> {
1160        match self.0 {
1161            ValueRepr::String(ref s, _) => Some(s.clone()),
1162            ValueRepr::SmallStr(ref s) => Some(Arc::from(s.as_str())),
1163            ValueRepr::Bytes(ref b) => Some(Arc::from(String::from_utf8_lossy(b))),
1164            _ => None,
1165        }
1166    }
1167
1168    /// If the value is a string, return it.
1169    ///
1170    /// This will also return well formed utf-8 bytes as string.
1171    pub fn as_str(&self) -> Option<&str> {
1172        match self.0 {
1173            ValueRepr::String(ref s, _) => Some(s as &str),
1174            ValueRepr::SmallStr(ref s) => Some(s.as_str()),
1175            ValueRepr::Bytes(ref b) => str::from_utf8(b).ok(),
1176            _ => None,
1177        }
1178    }
1179
1180    /// If this is an usize return it
1181    #[inline]
1182    pub fn as_usize(&self) -> Option<usize> {
1183        // This is manually implemented as the engine calls as_usize a few times
1184        // during execution on hotter paths.  This way we can avoid an unnecessary clone.
1185        match self.0 {
1186            ValueRepr::I64(val) => TryFrom::try_from(val).ok(),
1187            ValueRepr::U64(val) => TryFrom::try_from(val).ok(),
1188            _ => self.clone().try_into().ok(),
1189        }
1190    }
1191
1192    /// If this is an i64 return it
1193    pub fn as_i64(&self) -> Option<i64> {
1194        i64::try_from(self.clone()).ok()
1195    }
1196
1197    /// Returns the bytes of this value if they exist.
1198    pub fn as_bytes(&self) -> Option<&[u8]> {
1199        match self.0 {
1200            ValueRepr::String(ref s, _) => Some(s.as_bytes()),
1201            ValueRepr::SmallStr(ref s) => Some(s.as_str().as_bytes()),
1202            ValueRepr::Bytes(ref b) => Some(&b[..]),
1203            _ => None,
1204        }
1205    }
1206
1207    /// If the value is an object a reference to it is returned.
1208    ///
1209    /// The returned value is a reference to a type erased [`DynObject`].
1210    /// For a specific type use [`downcast_object`](Self::downcast_object)
1211    /// instead.
1212    pub fn as_object(&self) -> Option<&DynObject> {
1213        match self.0 {
1214            ValueRepr::Object(ref dy) => Some(dy),
1215            _ => None,
1216        }
1217    }
1218
1219    /// Returns the length of the contained value.
1220    ///
1221    /// Values without a length will return `None`.
1222    ///
1223    /// ```
1224    /// # use minijinja::value::Value;
1225    /// let seq = Value::from(vec![1, 2, 3, 4]);
1226    /// assert_eq!(seq.len(), Some(4));
1227    /// ```
1228    pub fn len(&self) -> Option<usize> {
1229        match self.0 {
1230            ValueRepr::String(ref s, _) => Some(s.chars().count()),
1231            ValueRepr::SmallStr(ref s) => Some(s.as_str().chars().count()),
1232            ValueRepr::Bytes(ref b) => Some(b.len()),
1233            ValueRepr::Object(ref dy) => dy.enumerator_len(),
1234            _ => None,
1235        }
1236    }
1237
1238    /// Looks up an attribute by attribute name.
1239    ///
1240    /// This this returns [`UNDEFINED`](Self::UNDEFINED) when an invalid key is
1241    /// resolved.  An error is returned if the value does not contain an object
1242    /// that has attributes.
1243    ///
1244    /// ```
1245    /// # use minijinja::value::Value;
1246    /// # fn test() -> Result<(), minijinja::Error> {
1247    /// let ctx = minijinja::context! {
1248    ///     foo => "Foo"
1249    /// };
1250    /// let value = ctx.get_attr("foo")?;
1251    /// assert_eq!(value.to_string(), "Foo");
1252    /// # Ok(()) }
1253    /// ```
1254    pub fn get_attr(&self, key: &str) -> Result<Value, Error> {
1255        let value = match self.0 {
1256            ValueRepr::Undefined(_) => return Err(Error::from(ErrorKind::UndefinedError)),
1257            ValueRepr::Object(ref dy) => dy.get_value(&Value::from(key)),
1258            _ => None,
1259        };
1260
1261        Ok(value.unwrap_or(Value::UNDEFINED))
1262    }
1263
1264    /// Alternative lookup strategy without error handling exclusively for context
1265    /// resolution.
1266    ///
1267    /// The main difference is that the return value will be `None` if the value is
1268    /// unable to look up the key rather than returning `Undefined` and errors will
1269    /// also not be created.
1270    pub(crate) fn get_attr_fast(&self, key: &str) -> Option<Value> {
1271        match self.0 {
1272            ValueRepr::Object(ref dy) => dy.get_value(&Value::from(key)),
1273            _ => None,
1274        }
1275    }
1276
1277    /// Looks up an index of the value.
1278    ///
1279    /// This is a shortcut for [`get_item`](Self::get_item).
1280    ///
1281    /// ```
1282    /// # use minijinja::value::Value;
1283    /// let seq = Value::from(vec![0u32, 1, 2]);
1284    /// let value = seq.get_item_by_index(1).unwrap();
1285    /// assert_eq!(value.try_into().ok(), Some(1));
1286    /// ```
1287    pub fn get_item_by_index(&self, idx: usize) -> Result<Value, Error> {
1288        self.get_item(&Value(ValueRepr::U64(idx as _)))
1289    }
1290
1291    /// Looks up an item (or attribute) by key.
1292    ///
1293    /// This is similar to [`get_attr`](Self::get_attr) but instead of using
1294    /// a string key this can be any key.  For instance this can be used to
1295    /// index into sequences.  Like [`get_attr`](Self::get_attr) this returns
1296    /// [`UNDEFINED`](Self::UNDEFINED) when an invalid key is looked up.
1297    ///
1298    /// ```
1299    /// # use minijinja::value::Value;
1300    /// let ctx = minijinja::context! {
1301    ///     foo => "Foo",
1302    /// };
1303    /// let value = ctx.get_item(&Value::from("foo")).unwrap();
1304    /// assert_eq!(value.to_string(), "Foo");
1305    /// ```
1306    pub fn get_item(&self, key: &Value) -> Result<Value, Error> {
1307        if let ValueRepr::Undefined(_) = self.0 {
1308            Err(Error::from(ErrorKind::UndefinedError))
1309        } else {
1310            Ok(self.get_item_opt(key).unwrap_or(Value::UNDEFINED))
1311        }
1312    }
1313
1314    /// Iterates over the value.
1315    ///
1316    /// Depending on the [`kind`](Self::kind) of the value the iterator
1317    /// has a different behavior.
1318    ///
1319    /// * [`ValueKind::Map`]: the iterator yields the keys of the map.
1320    /// * [`ValueKind::Seq`] / [`ValueKind::Iterable`]: the iterator yields the items in the sequence.
1321    /// * [`ValueKind::String`]: the iterator yields characters in a string.
1322    /// * [`ValueKind::None`] / [`ValueKind::Undefined`]: the iterator is empty.
1323    ///
1324    /// ```
1325    /// # use minijinja::value::Value;
1326    /// # fn test() -> Result<(), minijinja::Error> {
1327    /// let value = Value::from({
1328    ///     let mut m = std::collections::BTreeMap::new();
1329    ///     m.insert("foo", 42);
1330    ///     m.insert("bar", 23);
1331    ///     m
1332    /// });
1333    /// for key in value.try_iter()? {
1334    ///     let value = value.get_item(&key)?;
1335    ///     println!("{} = {}", key, value);
1336    /// }
1337    /// # Ok(()) }
1338    /// ```
1339    pub fn try_iter(&self) -> Result<ValueIter, Error> {
1340        match self.0 {
1341            ValueRepr::None | ValueRepr::Undefined(_) => Some(ValueIterImpl::Empty),
1342            ValueRepr::String(ref s, _) => {
1343                Some(ValueIterImpl::Chars(0, s.chars().count(), Arc::clone(s)))
1344            }
1345            ValueRepr::SmallStr(ref s) => Some(ValueIterImpl::Chars(
1346                0,
1347                s.as_str().chars().count(),
1348                Arc::from(s.as_str()),
1349            )),
1350            ValueRepr::Object(ref obj) => obj.try_iter().map(ValueIterImpl::Dyn),
1351            _ => None,
1352        }
1353        .map(|imp| ValueIter { imp })
1354        .ok_or_else(|| {
1355            Error::new(
1356                ErrorKind::InvalidOperation,
1357                format!("{} is not iterable", self.kind()),
1358            )
1359        })
1360    }
1361
1362    /// Returns a reversed view of this value.
1363    ///
1364    /// This is implemented for the following types with the following behaviors:
1365    ///
1366    /// * undefined or none: value returned unchanged.
1367    /// * string and bytes: returns a reversed version of that value
1368    /// * iterables: returns a reversed version of the iterable.  If the iterable is not
1369    ///   reversible itself, it consumes it and then reverses it.
1370    pub fn reverse(&self) -> Result<Value, Error> {
1371        match self.0 {
1372            ValueRepr::Undefined(_) | ValueRepr::None => Some(self.clone()),
1373            ValueRepr::String(ref s, _) => Some(Value::from(s.chars().rev().collect::<String>())),
1374            ValueRepr::SmallStr(ref s) => {
1375                // TODO: add small str optimization here
1376                Some(Value::from(s.as_str().chars().rev().collect::<String>()))
1377            }
1378            ValueRepr::Bytes(ref b) => Some(Value::from_bytes(
1379                b.iter().rev().copied().collect::<Vec<_>>(),
1380            )),
1381            ValueRepr::Object(ref o) => match o.enumerate() {
1382                Enumerator::NonEnumerable => None,
1383                Enumerator::Empty => Some(Value::make_iterable(|| None::<Value>.into_iter())),
1384                Enumerator::Seq(l) => {
1385                    let self_clone = o.clone();
1386                    Some(Value::make_iterable(move || {
1387                        let self_clone = self_clone.clone();
1388                        (0..l).rev().map(move |idx| {
1389                            self_clone.get_value(&Value::from(idx)).unwrap_or_default()
1390                        })
1391                    }))
1392                }
1393                Enumerator::Iter(iter) => {
1394                    let mut v = iter.collect::<Vec<_>>();
1395                    v.reverse();
1396                    Some(Value::make_object_iterable(v, move |v| {
1397                        Box::new(v.iter().cloned())
1398                    }))
1399                }
1400                Enumerator::RevIter(rev_iter) => {
1401                    let for_restart = self.clone();
1402                    let iter = Mutex::new(Some(rev_iter));
1403                    Some(Value::make_iterable(move || {
1404                        if let Some(iter) = iter.lock().unwrap().take() {
1405                            Box::new(iter) as Box<dyn Iterator<Item = Value> + Send + Sync>
1406                        } else {
1407                            match for_restart.reverse().and_then(|x| x.try_iter()) {
1408                                Ok(iterable) => Box::new(iterable)
1409                                    as Box<dyn Iterator<Item = Value> + Send + Sync>,
1410                                Err(err) => Box::new(Some(Value::from(err)).into_iter())
1411                                    as Box<dyn Iterator<Item = Value> + Send + Sync>,
1412                            }
1413                        }
1414                    }))
1415                }
1416                Enumerator::Str(s) => Some(Value::make_iterable(move || s.iter().rev().copied())),
1417                Enumerator::Values(mut v) => {
1418                    v.reverse();
1419                    Some(Value::make_object_iterable(v, move |v| {
1420                        Box::new(v.iter().cloned())
1421                    }))
1422                }
1423            },
1424            _ => None,
1425        }
1426        .ok_or_else(|| {
1427            Error::new(
1428                ErrorKind::InvalidOperation,
1429                format!("cannot reverse values of type {}", self.kind()),
1430            )
1431        })
1432    }
1433
1434    /// Returns some reference to the boxed object if it is of type `T`, or None if it isn’t.
1435    ///
1436    /// This is basically the "reverse" of [`from_object`](Self::from_object)
1437    /// and [`from_dyn_object`](Self::from_dyn_object). It's also a shortcut for
1438    /// [`downcast_ref`](DynObject::downcast_ref) on the return value of
1439    /// [`as_object`](Self::as_object).
1440    ///
1441    /// # Example
1442    ///
1443    /// ```rust
1444    /// # use minijinja::value::{Value, Object};
1445    /// use std::fmt;
1446    ///
1447    /// #[derive(Debug)]
1448    /// struct Thing {
1449    ///     id: usize,
1450    /// }
1451    ///
1452    /// impl Object for Thing {}
1453    ///
1454    /// let x_value = Value::from_object(Thing { id: 42 });
1455    /// let thing = x_value.downcast_object_ref::<Thing>().unwrap();
1456    /// assert_eq!(thing.id, 42);
1457    /// ```
1458    pub fn downcast_object_ref<T: 'static>(&self) -> Option<&T> {
1459        match self.0 {
1460            ValueRepr::Object(ref o) => o.downcast_ref(),
1461            _ => None,
1462        }
1463    }
1464
1465    /// Like [`downcast_object_ref`](Self::downcast_object_ref) but returns
1466    /// the actual object.
1467    pub fn downcast_object<T: 'static>(&self) -> Option<Arc<T>> {
1468        match self.0 {
1469            ValueRepr::Object(ref o) => o.downcast(),
1470            _ => None,
1471        }
1472    }
1473
1474    pub(crate) fn get_item_opt(&self, key: &Value) -> Option<Value> {
1475        fn index(value: &Value, len: impl Fn() -> Option<usize>) -> Option<usize> {
1476            match value.as_i64().and_then(|v| isize::try_from(v).ok()) {
1477                Some(i) if i < 0 => some!(len()).checked_sub(i.unsigned_abs()),
1478                Some(i) => Some(i as usize),
1479                None => None,
1480            }
1481        }
1482
1483        match self.0 {
1484            ValueRepr::Object(ref dy) => match dy.repr() {
1485                ObjectRepr::Map | ObjectRepr::Plain => dy.get_value(key),
1486                ObjectRepr::Iterable => {
1487                    if let Some(rv) = dy.get_value(key) {
1488                        return Some(rv);
1489                    }
1490                    // The default behavior is to try to index into the iterable
1491                    // as if nth() was called.  This lets one slice an array and
1492                    // then index into it.
1493                    if let Some(idx) = index(key, || dy.enumerator_len()) {
1494                        if let Some(mut iter) = dy.try_iter() {
1495                            if let Some(rv) = iter.nth(idx) {
1496                                return Some(rv);
1497                            }
1498                        }
1499                    }
1500                    None
1501                }
1502                ObjectRepr::Seq => {
1503                    let idx = index(key, || dy.enumerator_len()).map(Value::from);
1504                    dy.get_value(idx.as_ref().unwrap_or(key))
1505                }
1506            },
1507            ValueRepr::String(ref s, _) => {
1508                let idx = some!(index(key, || Some(s.chars().count())));
1509                s.chars().nth(idx).map(Value::from)
1510            }
1511            ValueRepr::SmallStr(ref s) => {
1512                let idx = some!(index(key, || Some(s.as_str().chars().count())));
1513                s.as_str().chars().nth(idx).map(Value::from)
1514            }
1515            ValueRepr::Bytes(ref b) => {
1516                let idx = some!(index(key, || Some(b.len())));
1517                b.get(idx).copied().map(Value::from)
1518            }
1519            _ => None,
1520        }
1521    }
1522
1523    /// Calls the value directly.
1524    ///
1525    /// If the value holds a function or macro, this invokes it.  Note that in
1526    /// MiniJinja there is a separate namespace for methods on objects and callable
1527    /// items.  To call methods (which should be a rather rare occurrence) you
1528    /// have to use [`call_method`](Self::call_method).
1529    ///
1530    /// The `args` slice is for the arguments of the function call.  To pass
1531    /// keyword arguments use the [`Kwargs`] type.
1532    ///
1533    /// Usually the state is already available when it's useful to call this method,
1534    /// but when it's not available you can get a fresh template state straight
1535    /// from the [`Template`](crate::Template) via [`new_state`](crate::Template::new_state).
1536    ///
1537    /// ```
1538    /// # use minijinja::{Environment, value::{Value, Kwargs}};
1539    /// # let mut env = Environment::new();
1540    /// # env.add_template("foo", "").unwrap();
1541    /// # let tmpl = env.get_template("foo").unwrap();
1542    /// # let state = tmpl.new_state(); let state = &state;
1543    /// let func = Value::from_function(|v: i64, kwargs: Kwargs| {
1544    ///     v * kwargs.get::<i64>("mult").unwrap_or(1)
1545    /// });
1546    /// let rv = func.call(
1547    ///     state,
1548    ///     &[
1549    ///         Value::from(42),
1550    ///         Value::from(Kwargs::from_iter([("mult", Value::from(2))])),
1551    ///     ],
1552    /// ).unwrap();
1553    /// assert_eq!(rv, Value::from(84));
1554    /// ```
1555    ///
1556    /// With the [`args!`](crate::args) macro creating an argument slice is
1557    /// simplified:
1558    ///
1559    /// ```
1560    /// # use minijinja::{Environment, args, value::{Value, Kwargs}};
1561    /// # let mut env = Environment::new();
1562    /// # env.add_template("foo", "").unwrap();
1563    /// # let tmpl = env.get_template("foo").unwrap();
1564    /// # let state = tmpl.new_state(); let state = &state;
1565    /// let func = Value::from_function(|v: i64, kwargs: Kwargs| {
1566    ///     v * kwargs.get::<i64>("mult").unwrap_or(1)
1567    /// });
1568    /// let rv = func.call(state, args!(42, mult => 2)).unwrap();
1569    /// assert_eq!(rv, Value::from(84));
1570    /// ```
1571    pub fn call(&self, state: &State, args: &[Value]) -> Result<Value, Error> {
1572        if let ValueRepr::Object(ref dy) = self.0 {
1573            dy.call(state, args)
1574        } else {
1575            Err(Error::new(
1576                ErrorKind::InvalidOperation,
1577                format!("value of type {} is not callable", self.kind()),
1578            ))
1579        }
1580    }
1581
1582    /// Calls a method on the value.
1583    ///
1584    /// The name of the method is `name`, the arguments passed are in the `args`
1585    /// slice.
1586    pub fn call_method(&self, state: &State, name: &str, args: &[Value]) -> Result<Value, Error> {
1587        match self._call_method(state, name, args) {
1588            Ok(rv) => Ok(rv),
1589            Err(mut err) => {
1590                if err.kind() == ErrorKind::UnknownMethod {
1591                    if let Some(ref callback) = state.env().unknown_method_callback {
1592                        match callback(state, self, name, args) {
1593                            Ok(result) => return Ok(result),
1594                            Err(callback_err) => {
1595                                // if the callback fails with the same error, we
1596                                // want to also attach the default detail if
1597                                // it's missing
1598                                if callback_err.kind() == ErrorKind::UnknownMethod {
1599                                    err = callback_err;
1600                                } else {
1601                                    return Err(err);
1602                                }
1603                            }
1604                        }
1605                    }
1606                    if err.detail().is_none() {
1607                        err.set_detail(format!("{} has no method named {}", self.kind(), name));
1608                    }
1609                }
1610                Err(err)
1611            }
1612        }
1613    }
1614
1615    fn _call_method(&self, state: &State, name: &str, args: &[Value]) -> Result<Value, Error> {
1616        if let Some(object) = self.as_object() {
1617            object.call_method(state, name, args)
1618        } else {
1619            Err(Error::from(ErrorKind::UnknownMethod))
1620        }
1621    }
1622
1623    #[cfg(feature = "builtins")]
1624    pub(crate) fn get_path(&self, path: &str) -> Result<Value, Error> {
1625        let mut rv = self.clone();
1626        for part in path.split('.') {
1627            if let Ok(num) = part.parse::<usize>() {
1628                rv = ok!(rv.get_item_by_index(num));
1629            } else {
1630                rv = ok!(rv.get_attr(part));
1631            }
1632        }
1633        Ok(rv)
1634    }
1635
1636    #[cfg(feature = "builtins")]
1637    pub(crate) fn get_path_or_default(&self, path: &str, default: &Value) -> Value {
1638        match self.get_path(path) {
1639            Err(_) => default.clone(),
1640            Ok(val) if val.is_undefined() => default.clone(),
1641            Ok(val) => val,
1642        }
1643    }
1644}
1645
1646impl Serialize for Value {
1647    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1648    where
1649        S: Serializer,
1650    {
1651        // enable round tripping of values
1652        if serializing_for_value() {
1653            let handle = LAST_VALUE_HANDLE.with(|x| {
1654                // we are okay with overflowing the handle here because these values only
1655                // live for a very short period of time and it's not likely that you run out
1656                // of an entire u32 worth of handles in a single serialization operation.
1657                let rv = x.get().wrapping_add(1);
1658                x.set(rv);
1659                rv
1660            });
1661            VALUE_HANDLES.with(|handles| handles.borrow_mut().insert(handle, self.clone()));
1662
1663            // we serialize this into a tuple struct as a form of in-band signalling
1664            // we can detect.  This also will fail with a somewhat acceptable error
1665            // for flattening operations.  See https://github.com/mitsuhiko/minijinja/issues/222
1666            let mut s = ok!(serializer.serialize_tuple_struct(VALUE_HANDLE_MARKER, 1));
1667            ok!(s.serialize_field(&handle));
1668            return s.end();
1669        }
1670
1671        match self.0 {
1672            ValueRepr::Bool(b) => serializer.serialize_bool(b),
1673            ValueRepr::U64(u) => serializer.serialize_u64(u),
1674            ValueRepr::I64(i) => serializer.serialize_i64(i),
1675            ValueRepr::F64(f) => serializer.serialize_f64(f),
1676            ValueRepr::None | ValueRepr::Undefined(_) | ValueRepr::Invalid(_) => {
1677                serializer.serialize_unit()
1678            }
1679            ValueRepr::U128(u) => serializer.serialize_u128(u.0),
1680            ValueRepr::I128(i) => serializer.serialize_i128(i.0),
1681            ValueRepr::String(ref s, _) => serializer.serialize_str(s),
1682            ValueRepr::SmallStr(ref s) => serializer.serialize_str(s.as_str()),
1683            ValueRepr::Bytes(ref b) => serializer.serialize_bytes(b),
1684            ValueRepr::Object(ref o) => match o.repr() {
1685                ObjectRepr::Plain => serializer.serialize_str(&o.to_string()),
1686                ObjectRepr::Seq | ObjectRepr::Iterable => {
1687                    use serde::ser::SerializeSeq;
1688                    let mut seq = ok!(serializer.serialize_seq(o.enumerator_len()));
1689                    if let Some(iter) = o.try_iter() {
1690                        for item in iter {
1691                            ok!(seq.serialize_element(&item));
1692                        }
1693                    }
1694
1695                    seq.end()
1696                }
1697                ObjectRepr::Map => {
1698                    use serde::ser::SerializeMap;
1699                    let mut map = ok!(serializer.serialize_map(None));
1700                    if let Some(iter) = o.try_iter_pairs() {
1701                        for (key, value) in iter {
1702                            ok!(map.serialize_entry(&key, &value));
1703                        }
1704                    }
1705
1706                    map.end()
1707                }
1708            },
1709        }
1710    }
1711}
1712
1713/// Helper to create an iterator proxy that borrows from an object.
1714pub(crate) fn mapped_enumerator<F, T>(obj: &Arc<T>, maker: F) -> Enumerator
1715where
1716    T: Object + 'static,
1717    F: for<'a> FnOnce(&'a T) -> Box<dyn Iterator<Item = Value> + Send + Sync + 'a>,
1718{
1719    struct Iter {
1720        iter: Box<dyn Iterator<Item = Value> + Send + Sync + 'static>,
1721        _object: DynObject,
1722    }
1723
1724    impl Iterator for Iter {
1725        type Item = Value;
1726
1727        fn next(&mut self) -> Option<Self::Item> {
1728            self.iter.next()
1729        }
1730
1731        fn size_hint(&self) -> (usize, Option<usize>) {
1732            self.iter.size_hint()
1733        }
1734    }
1735
1736    // SAFETY: this is safe because the object is kept alive by the iter
1737    let iter = unsafe {
1738        std::mem::transmute::<Box<dyn Iterator<Item = _>>, Box<dyn Iterator<Item = _> + Send + Sync>>(
1739            maker(obj),
1740        )
1741    };
1742    let _object = DynObject::new(obj.clone());
1743    Enumerator::Iter(Box::new(Iter { iter, _object }))
1744}
1745
1746/// Utility to iterate over values.
1747pub struct ValueIter {
1748    imp: ValueIterImpl,
1749}
1750
1751impl Iterator for ValueIter {
1752    type Item = Value;
1753
1754    fn next(&mut self) -> Option<Self::Item> {
1755        match self.imp {
1756            ValueIterImpl::Empty => None,
1757            ValueIterImpl::Chars(ref mut offset, ref mut len, ref s) => {
1758                (s as &str)[*offset..].chars().next().map(|c| {
1759                    *offset += c.len_utf8();
1760                    *len -= 1;
1761                    Value::from(c)
1762                })
1763            }
1764            ValueIterImpl::Dyn(ref mut iter) => iter.next(),
1765        }
1766    }
1767
1768    fn size_hint(&self) -> (usize, Option<usize>) {
1769        match self.imp {
1770            ValueIterImpl::Empty => (0, Some(0)),
1771            ValueIterImpl::Chars(_, len, _) => (0, Some(len)),
1772            ValueIterImpl::Dyn(ref iter) => iter.size_hint(),
1773        }
1774    }
1775}
1776
1777impl fmt::Debug for ValueIter {
1778    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1779        f.debug_struct("ValueIterator").finish()
1780    }
1781}
1782
1783enum ValueIterImpl {
1784    Empty,
1785    Chars(usize, usize, Arc<str>),
1786    Dyn(Box<dyn Iterator<Item = Value> + Send + Sync>),
1787}
1788
1789impl From<Error> for Value {
1790    fn from(value: Error) -> Self {
1791        Value(ValueRepr::Invalid(Arc::new(value)))
1792    }
1793}
1794
1795#[cfg(test)]
1796mod tests {
1797    use super::*;
1798
1799    use similar_asserts::assert_eq;
1800
1801    #[test]
1802    fn test_dynamic_object_roundtrip() {
1803        use std::sync::atomic::{self, AtomicUsize};
1804
1805        #[derive(Debug, Clone)]
1806        struct X(Arc<AtomicUsize>);
1807
1808        impl Object for X {
1809            fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
1810                match key.as_str()? {
1811                    "value" => Some(Value::from(self.0.load(atomic::Ordering::Relaxed))),
1812                    _ => None,
1813                }
1814            }
1815
1816            fn enumerate(self: &Arc<Self>) -> Enumerator {
1817                Enumerator::Str(&["value"])
1818            }
1819
1820            fn render(self: &Arc<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1821                write!(f, "{}", self.0.load(atomic::Ordering::Relaxed))
1822            }
1823        }
1824
1825        let x = Arc::new(X(Default::default()));
1826        let x_value = Value::from_dyn_object(x.clone());
1827        x.0.fetch_add(42, atomic::Ordering::Relaxed);
1828        let x_clone = Value::from_serialize(&x_value);
1829        x.0.fetch_add(23, atomic::Ordering::Relaxed);
1830
1831        assert_eq!(x_value.to_string(), "65");
1832        assert_eq!(x_clone.to_string(), "65");
1833    }
1834
1835    #[test]
1836    fn test_string_char() {
1837        let val = Value::from('a');
1838        assert_eq!(char::try_from(val).unwrap(), 'a');
1839        let val = Value::from("a");
1840        assert_eq!(char::try_from(val).unwrap(), 'a');
1841        let val = Value::from("wat");
1842        assert!(char::try_from(val).is_err());
1843    }
1844
1845    #[test]
1846    #[cfg(target_pointer_width = "64")]
1847    fn test_sizes() {
1848        assert_eq!(std::mem::size_of::<Value>(), 24);
1849    }
1850}