git.delta.rocks / jrsonnet / refs/commits / 098d931f0d92

difftreelog

fix #[derive(Typed)] should lazily process Thunks

Yaroslav Bolyukin2024-08-15parent: #74ea504.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth
957957
958 /// Tries to insert value, returns an error if it was already defined958 /// Tries to insert value, returns an error if it was already defined
959 pub fn try_value(self, value: impl Into<Val>) -> Result<()> {959 pub fn try_value(self, value: impl Into<Val>) -> Result<()> {
960 self.thunk(Thunk::evaluated(value.into()))960 self.try_thunk(Thunk::evaluated(value.into()))
961 }961 }
962 pub fn thunk(self, value: impl Into<Thunk<Val>>) -> Result<()> {962 pub fn try_thunk(self, value: impl Into<Thunk<Val>>) -> Result<()> {
963 self.binding(MaybeUnbound::Bound(value.into()))963 self.binding(MaybeUnbound::Bound(value.into()))
964 }964 }
965 pub fn bindable(self, bindable: impl Unbound<Bound = Val>) -> Result<()> {965 pub fn bindable(self, bindable: impl Unbound<Bound = Val>) -> Result<()> {
modifiedcrates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -477,6 +477,7 @@
 	ident: Ident,
 	ty: Type,
 	is_option: bool,
+	is_lazy: bool,
 }
 impl TypedField {
 	fn parse(field: &syn::Field) -> Result<Self> {
@@ -503,11 +504,14 @@
 			));
 		}
 
+		let is_lazy = type_is_path(&ty, "Thunk").is_some();
+
 		Ok(Self {
 			attr,
 			ident,
 			ty,
 			is_option,
+			is_lazy,
 		})
 	}
 	/// None if this field is flattened in jsonnet output
@@ -596,21 +600,33 @@
 				} else {
 					quote! {}
 				};
+				let value = if self.is_lazy {
+					quote! {
+						out.field(#name)
+							#hide
+							#add
+							.try_thunk(<#ty as Typed>::into_lazy_untyped(value))?;
+					}
+				} else {
+					quote! {
+						out.field(#name)
+							#hide
+							#add
+							.try_value(<#ty as Typed>::into_untyped(value)?)?;
+					}
+				};
 				if self.is_option {
 					quote! {
 						if let Some(value) = self.#ident {
-							out.field(#name)
-								#hide
-								#add
-								.try_value(<#ty as Typed>::into_untyped(value)?)?;
+							#value
 						}
 					}
 				} else {
 					quote! {
-						out.field(#name)
-							#hide
-							#add
-							.try_value(<#ty as Typed>::into_untyped(self.#ident)?)?;
+						{
+							let value = self.#ident;
+							#value
+						}
 					}
 				}
 			},