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}