Repository: mitsuhiko/minijinja
Pull request #482 (2024-04-08 18:16:04)

Introduce Value::from_serialize for 1.x
This introduces the same API as in MiniJinja 2.x to make it easier to upgrade.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 738f029..84a7af1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,8 @@ All notable changes to MiniJinja are documented here.
 
 - Added support for `Option<Into<Value>>` as return value from
   functions.  #452
+- Deprecated `Value::from_serializable` for the improved replacement
+  method `Value::from_serialize`. #482
 
 ## 1.0.16
 
diff --git a/examples/deserialize/src/main.rs b/examples/deserialize/src/main.rs
index b5c0717..96dc35f 100644
--- a/examples/deserialize/src/main.rs
+++ b/examples/deserialize/src/main.rs
@@ -43,7 +43,7 @@ fn main() {
     );
 
     // Second example shows how you can deserialize directly from a value
-    let point_value = Value::from_serializable(&point);
+    let point_value = Value::from_serialize(&point);
     println!("Point serialized as value: {}", point_value);
     let point_again = Point::deserialize(point_value).unwrap();
     println!("Point deserialization: {:?}", point_again);
diff --git a/examples/load-lazy/src/main.rs b/examples/load-lazy/src/main.rs
index ee6e239..de247fc 100644
--- a/examples/load-lazy/src/main.rs
+++ b/examples/load-lazy/src/main.rs
@@ -40,7 +40,7 @@ fn load_json(name: &str) -> Option<Value> {
     rv.set_extension("json");
     let contents = fs::read(&rv).ok()?;
     let parsed: serde_json::Value = serde_json::from_slice(&contents[..]).ok()?;
-    Some(Value::from_serializable(&parsed))
+    Some(Value::from_serialize(parsed))
 }
 
 fn main() {
diff --git a/examples/load-resource/src/main.rs b/examples/load-resource/src/main.rs
index 38e8d88..a1c0fdd 100644
--- a/examples/load-resource/src/main.rs
+++ b/examples/load-resource/src/main.rs
@@ -16,7 +16,7 @@ fn load_data(filename: &str) -> Result<Value, Error> {
     })?;
     let parsed: serde_json::Value = serde_json::from_slice(&contents[..])
         .map_err(|err| Error::new(ErrorKind::InvalidOperation, "invalid JSON").with_source(err))?;
-    Ok(Value::from_serializable(&parsed))
+    Ok(Value::from_serialize(parsed))
 }
 
 fn main() {
diff --git a/minijinja-stack-ref/src/lib.rs b/minijinja-stack-ref/src/lib.rs
index b258fd5..ebf4096 100644
--- a/minijinja-stack-ref/src/lib.rs
+++ b/minijinja-stack-ref/src/lib.rs
@@ -272,7 +272,7 @@ pub fn reborrow<T: ?Sized, R>(obj: &T, f: for<'a> fn(&'a T, &'a Scope) -> R) ->
 ///                     scope.seq_object_ref(&slf.values[..])
 ///                 }))
 ///             } else {
-///                 Some(Value::from_serializable(&self.values))
+///                 Some(Value::from_serialize(&self.values))
 ///             },
 ///             _ => None
 ///         }
diff --git a/minijinja/src/expression.rs b/minijinja/src/expression.rs
index dedfcf7..6784c3f 100644
--- a/minijinja/src/expression.rs
+++ b/minijinja/src/expression.rs
@@ -88,7 +88,7 @@ impl<'env, 'source> Expression<'env, 'source> {
     pub fn eval<S: Serialize>(&self, ctx: S) -> Result<Value, Error> {
         // reduce total amount of code faling under mono morphization into
         // this function, and share the rest in _eval.
-        self._eval(Value::from_serializable(&ctx))
+        self._eval(Value::from_serialize(&ctx))
     }
 
     /// Returns a set of all undeclared variables in the expression.
diff --git a/minijinja/src/macros.rs b/minijinja/src/macros.rs
index 48aad23..e07b65f 100644
--- a/minijinja/src/macros.rs
+++ b/minijinja/src/macros.rs
@@ -166,7 +166,7 @@ macro_rules! __context_pair {
         $crate::__context::add(
             &mut $ctx,
             stringify!($key),
-            $crate::value::Value::from_serializable(&$value),
+            $crate::value::Value::from_serialize(&$value),
         );
     };
 }
@@ -193,7 +193,7 @@ macro_rules! __context_pair {
 /// ```
 ///
 /// Note that this like [`context!`](crate::context) goes through
-/// [`Value::from_serializable`](crate::value::Value::from_serializable).
+/// [`Value::from_serialize`](crate::value::Value::from_serialize).
 #[macro_export]
 macro_rules! args {
     () => { &[][..] as &[$crate::value::Value] };
@@ -235,17 +235,17 @@ macro_rules! __args_helper {
     // `$args` or `$kwargs` depending on type.
     (peel $args:ident, $kwargs:ident, $has_kwargs:ident, []) => {};
     (peel $args:ident, $kwargs:ident, $has_kwargs:ident, [$name:ident => $expr:expr]) => {
-        $kwargs.push((stringify!($name), $crate::value::Value::from_serializable(&$expr)));
+        $kwargs.push((stringify!($name), $crate::value::Value::from_serialize(&$expr)));
     };
     (peel $args:ident, $kwargs:ident, $has_kwargs:ident, [$name:ident => $expr:expr, $($rest:tt)*]) => {
-        $kwargs.push((stringify!($name), $crate::value::Value::from_serializable(&$expr)));
+        $kwargs.push((stringify!($name), $crate::value::Value::from_serialize(&$expr)));
         $crate::__args_helper!(peel $args, $kwargs, true, [$($rest)*]);
     };
     (peel $args:ident, $kwargs:ident, false, [$expr:expr]) => {
-        $args.push($crate::value::Value::from_serializable(&$expr));
+        $args.push($crate::value::Value::from_serialize(&$expr));
     };
     (peel $args:ident, $kwargs:ident, false, [$expr:expr, $($rest:tt)*]) => {
-        $args.push($crate::value::Value::from_serializable(&$expr));
+        $args.push($crate::value::Value::from_serialize(&$expr));
         $crate::__args_helper!(peel $args, $kwargs, false, [$($rest)*]);
     };
 }
diff --git a/minijinja/src/template.rs b/minijinja/src/template.rs
index 827b72a..0f1c9fd 100644
--- a/minijinja/src/template.rs
+++ b/minijinja/src/template.rs
@@ -114,7 +114,7 @@ impl<'env, 'source> Template<'env, 'source> {
     pub fn render<S: Serialize>(&self, ctx: S) -> Result<String, Error> {
         // reduce total amount of code faling under mono morphization into
         // this function, and share the rest in _render.
-        self._render(Value::from_serializable(&ctx)).map(|x| x.0)
+        self._render(Value::from_serialize(&ctx)).map(|x| x.0)
     }
 
     /// Like [`render`](Self::render) but also return the evaluated [`State`].
@@ -140,7 +140,7 @@ impl<'env, 'source> Template<'env, 'source> {
     ) -> Result<(String, State<'_, 'env>), Error> {
         // reduce total amount of code faling under mono morphization into
         // this function, and share the rest in _render.
-        self._render(Value::from_serializable(&ctx))
+        self._render(Value::from_serialize(&ctx))
     }
 
     fn _render(&self, root: Value) -> Result<(String, State<'_, 'env>), Error> {
@@ -174,7 +174,7 @@ impl<'env, 'source> Template<'env, 'source> {
     ) -> Result<State<'_, 'env>, Error> {
         let mut wrapper = WriteWrapper { w, err: None };
         self._eval(
-            Value::from_serializable(&ctx),
+            Value::from_serialize(&ctx),
             &mut Output::with_write(&mut wrapper),
         )
         .map(|(_, state)| state)
@@ -203,7 +203,7 @@ impl<'env, 'source> Template<'env, 'source> {
     ///
     /// For more information see [`State`].
     pub fn eval_to_state<S: Serialize>(&self, ctx: S) -> Result<State<'_, 'env>, Error> {
-        let root = Value::from_serializable(&ctx);
+        let root = Value::from_serialize(&ctx);
         let mut out = Output::null();
         let vm = Vm::new(self.env);
         let state = ok!(vm.eval(
diff --git a/minijinja/src/value/mod.rs b/minijinja/src/value/mod.rs
index 4f1b112..61f62d9 100644
--- a/minijinja/src/value/mod.rs
+++ b/minijinja/src/value/mod.rs
@@ -58,11 +58,11 @@
 //!
 //! MiniJinja will usually however create values via an indirection via [`serde`] when
 //! a template is rendered or an expression is evaluated.  This can also be
-//! triggered manually by using the [`Value::from_serializable`] method:
+//! triggered manually by using the [`Value::from_serialize`] method:
 //!
 //! ```
 //! # use minijinja::value::Value;
-//! let value = Value::from_serializable(&[1, 2, 3]);
+//! let value = Value::from_serialize(&[1, 2, 3]);
 //! ```
 //!
 //! The inverse of that operation is to pass a value directly as serializer to
@@ -591,7 +591,7 @@ impl Value {
     ///
     /// ```
     /// # use minijinja::value::Value;
-    /// let val = Value::from_serializable(&vec![1, 2, 3]);
+    /// let val = Value::from_serialize(&vec![1, 2, 3]);
     /// ```
     ///
     /// This method does not fail but it might return a value that is not valid.  Such
@@ -606,6 +606,20 @@ impl Value {
     /// is to use the [`Value`] type as serializer.  You can pass a value into the
     /// [`deserialize`](serde::Deserialize::deserialize) method of a type that supports
     /// serde deserialization.
+    pub fn from_serialize<T: Serialize>(value: T) -> Value {
+        let _serialization_guard = mark_internal_serialization();
+        let _optimization_guard = value_optimization();
+        transform(value)
+    }
+
+    /// Deprecated original name of [`Value::from_serialize`].
+    ///
+    /// This method was replaced by the more generic method [`Value::from_serialize`]
+    /// which also takes values by either reference or value.
+    #[deprecated(
+        since = "1.17.0",
+        note = "this method was replaced by Value::from_serialize"
+    )]
     pub fn from_serializable<T: Serialize>(value: &T) -> Value {
         let _serialization_guard = mark_internal_serialization();
         let _optimization_guard = value_optimization();
@@ -1518,7 +1532,7 @@ mod tests {
         let x = Arc::new(X(Default::default()));
         let x_value = Value::from(x.clone());
         x.0.fetch_add(42, atomic::Ordering::Relaxed);
-        let x_clone = Value::from_serializable(&x_value);
+        let x_clone = Value::from_serialize(&x_value);
         x.0.fetch_add(23, atomic::Ordering::Relaxed);
 
         assert_eq!(x_value.to_string(), "65");


Test patch:
diff --git a/minijinja/tests/test_deserialization.rs b/minijinja/tests/test_deserialization.rs
index e0d0484..e6ac798 100644
--- a/minijinja/tests/test_deserialization.rs
+++ b/minijinja/tests/test_deserialization.rs
@@ -112,7 +112,7 @@ fn test_invalid() {
         }
     }
 
-    let v = Value::from_serializable(&X);
+    let v = Value::from_serialize(X);
     assert_eq!(v.to_string(), "<invalid value: meh>");
 
     let err = bool::deserialize(v).unwrap_err();
diff --git a/minijinja/tests/test_value.rs b/minijinja/tests/test_value.rs
index 8884505..e1904dd 100644
--- a/minijinja/tests/test_value.rs
+++ b/minijinja/tests/test_value.rs
@@ -121,7 +121,7 @@ fn test_sort_different_types() {
 #[test]
 fn test_safe_string_roundtrip() {
     let v = Value::from_safe_string("<b>HTML</b>".into());
-    let v2 = Value::from_serializable(&v);
+    let v2 = Value::from_serialize(&v);
     assert!(v.is_safe());
     assert!(v2.is_safe());
     assert_eq!(v.to_string(), v2.to_string());
@@ -130,7 +130,7 @@ fn test_safe_string_roundtrip() {
 #[test]
 fn test_undefined_roundtrip() {
     let v = Value::UNDEFINED;
-    let v2 = Value::from_serializable(&v);
+    let v2 = Value::from_serialize(&v);
     assert!(v.is_undefined());
     assert!(v2.is_undefined());
 }
diff --git a/minijinja/tests/test_vm.rs b/minijinja/tests/test_vm.rs
index 08819a7..af7a4dd 100644
--- a/minijinja/tests/test_vm.rs
+++ b/minijinja/tests/test_vm.rs
@@ -14,7 +14,7 @@ pub fn simple_eval<S: serde::Serialize>(
     let env = Environment::new();
     let empty_blocks = BTreeMap::new();
     let vm = Vm::new(&env);
-    let root = Value::from_serializable(&ctx);
+    let root = Value::from_serialize(&ctx);
     let mut rv = String::new();
     let mut output = make_string_output(&mut rv);
     vm.eval(