Repository: mitsuhiko/minijinja
Pull request #487 (2024-04-10 10:07:00)

Introduce Value::make_one_shot_iterator in 1.x
Introduces the API with the same name from 2.x


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ae24db..8fdfd5e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
 
 All notable changes to MiniJinja are documented here.
 
+## 1.0.19
+
+- Deprecated `Value::from_iterator` and introduced replacement
+  `Value::make_one_shot_iterator` API which also exists in 2.x.  #487
+
 ## 1.0.18
 
 - Fixed an endless loop in `undeclared_variables`.  #486
diff --git a/examples/dynamic-objects/src/main.rs b/examples/dynamic-objects/src/main.rs
index 378d5b8..f9128cb 100644
--- a/examples/dynamic-objects/src/main.rs
+++ b/examples/dynamic-objects/src/main.rs
@@ -74,7 +74,10 @@ fn main() {
     env.add_function("cycler", make_cycler);
     env.add_global("magic", Value::from_object(Magic));
     env.add_global("seq", Value::from_seq_object(SimpleDynamicSeq));
-    env.add_global("real_iter", Value::from_iterator((0..10).chain(20..30)));
+    env.add_global(
+        "real_iter",
+        Value::make_one_shot_iterator((0..10).chain(20..30)),
+    );
     env.add_template("template.html", include_str!("template.html"))
         .unwrap();
 
diff --git a/minijinja/src/value/mod.rs b/minijinja/src/value/mod.rs
index 61f62d9..80bbe23 100644
--- a/minijinja/src/value/mod.rs
+++ b/minijinja/src/value/mod.rs
@@ -34,11 +34,11 @@
 //!
 //! For certain types of iterators (`Send` + `Sync` + `'static`) it's also
 //! possible to make the value lazily iterate over the value by using the
-//! `Value::from_iterator` function instead:
+//! `Value::make_one_shot_iterator` function instead:
 //!
 //! ```
 //! # use minijinja::value::Value;
-//! let value: Value = Value::from_iterator(1..10);
+//! let value: Value = Value::make_one_shot_iterator(1..10);
 //! ```
 //!
 //! To to into the inverse directly the various [`TryFrom`](std::convert::TryFrom)
@@ -641,8 +641,21 @@ impl Value {
     ///
     /// ```
     /// # use minijinja::value::Value;
-    /// let val = Value::from_iterator(0..10);
+    /// let val = Value::make_one_shot_iterator(0..10);
     /// ```
+    pub fn make_one_shot_iterator<I, T>(iter: I) -> Value
+    where
+        I: Iterator<Item = T> + Send + Sync + 'static,
+        T: Into<Value> + Send + Sync + 'static,
+    {
+        Value::from_object(SimpleIteratorObject(Mutex::new(iter.fuse())))
+    }
+
+    /// Deprecated alternative to [`Value::make_one_shot_iterator`].
+    #[deprecated(
+        since = "1.19.0",
+        note = "this method was replaced by Value::make_one_shot_iterator"
+    )]
     pub fn from_iterator<I, T>(iter: I) -> Value
     where
         I: Iterator<Item = T> + Send + Sync + 'static,
diff --git a/minijinja/src/value/object.rs b/minijinja/src/value/object.rs
index 740f167..bda6e8d 100644
--- a/minijinja/src/value/object.rs
+++ b/minijinja/src/value/object.rs
@@ -214,7 +214,7 @@ pub enum ObjectKind<'a> {
     ///
     /// Requires that the object implements [`IteratorObject`].  It's not
     /// recommended to implement this, instead one should directly pass
-    /// iterators to [`Value::from_iterator`].
+    /// iterators to [`Value::make_one_shot_iterator`].
     Iterator(&'a dyn IteratorObject),
 }
 


Test patch:
diff --git a/minijinja/tests/test_value.rs b/minijinja/tests/test_value.rs
index e1904dd..977358c 100644
--- a/minijinja/tests/test_value.rs
+++ b/minijinja/tests/test_value.rs
@@ -513,7 +513,7 @@ fn test_seq_object_borrow() {
 
 #[test]
 fn test_iterator() {
-    let value = Value::from_iterator(0..10);
+    let value = Value::make_one_shot_iterator(0..10);
     assert_eq!(value.to_string(), "<iterator>");
     let rv = render!(
         "{% for item in iter %}[{{ item }}]{% endfor %}",
@@ -523,7 +523,7 @@ fn test_iterator() {
 
     let rv = render!(
         "{% for item in iter %}- {{ item }}: {{ loop.index }} / {{ loop.length }}\n{% endfor %}",
-        iter => Value::from_iterator('a'..'f')
+        iter => Value::make_one_shot_iterator('a'..'f')
     );
     assert_snapshot!(rv, @r###"
     - a: 1 / 5
@@ -535,7 +535,7 @@ fn test_iterator() {
 
     let rv = render!(
         "{% for item in iter %}- {{ item }}: {{ loop.index }} / {{ loop.length|default('?') }}\n{% endfor %}",
-     iter => Value::from_iterator((0..10).filter(|x| x % 2 == 0))
+     iter => Value::make_one_shot_iterator((0..10).filter(|x| x % 2 == 0))
     );
     assert_snapshot!(rv, @r###"
     - 0: 1 / ?