Skip to main content

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