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