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