git.delta.rocks / jrsonnet / refs/commits / a10f2cf96ed8

difftreelog

feat(macros) #[typed(method)]

tzummrkzYaroslav Bolyukin2026-04-25parent: #9fe9fbb.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -127,6 +127,7 @@
 	syn::custom_keyword!(flatten);
 	syn::custom_keyword!(add);
 	syn::custom_keyword!(hide);
+	syn::custom_keyword!(method);
 	syn::custom_keyword!(ok);
 }
 
@@ -381,18 +382,8 @@
 
 	let name = &fun.sig.ident;
 	let vis = &fun.vis;
-	let static_ext = if attr.fields.is_empty() {
-		quote! {
-			impl #name {
-				pub const INST: &'static dyn StaticBuiltin = &#name {};
-			}
-			impl StaticBuiltin for #name {}
-		}
-	} else {
-		quote! {}
-	};
 	let static_derive_copy = if attr.fields.is_empty() {
-		quote! {, Copy}
+		quote! {, Copy, Default}
 	} else {
 		quote! {}
 	};
@@ -409,7 +400,7 @@
 		const _: () = {
 			use ::jrsonnet_evaluator::{
 				State, Val,
-				function::{builtin::{Builtin, StaticBuiltin}, FunctionSignature, ParamParse, ParamName, ParamDefault, CallLocation},
+				function::{builtin::Builtin, FunctionSignature, ParamParse, ParamName, ParamDefault, CallLocation},
 				Result, Context, typed::{Typed, FromUntyped, IntoUntypedResult},
 				parser::Span, params, Thunk,
 			};
@@ -417,7 +408,6 @@
 				#(#params_desc)*
 			);
 
-			#static_ext
 			impl Builtin for #name
 			where
 				Self: 'static
modifiedcrates/jrsonnet-macros/src/typed.rsdiffbeforeafterboth
1use proc_macro2::TokenStream;1use proc_macro2::TokenStream;
2use quote::quote;2use quote::quote;
3use syn::{3use syn::{
4 DeriveInput, Error, Ident, LitStr, Result, Token, Type, parenthesized,4 parenthesized,
5 parse::{Parse, ParseStream},5 parse::{Parse, ParseStream},
6 spanned::Spanned as _,6 spanned::Spanned as _,
7 token,7 token, DeriveInput, Error, Ident, LitStr, Result, Token, Type,
8};8};
99
10use crate::{extract_type_from_option, kw, names::Names, parse_attr, type_is_path};10use crate::{extract_type_from_option, kw, names::Names, parse_attr, type_is_path};
22 add: bool,22 add: bool,
23 // Should it be `field::` instead of `field:`23 // Should it be `field::` instead of `field:`
24 hide: bool,24 hide: bool,
25 // Builtin value
26 method: bool,
25}27}
26impl Parse for TypedAttr {28impl Parse for TypedAttr {
27 fn parse(input: ParseStream) -> syn::Result<Self> {29 fn parse(input: ParseStream) -> syn::Result<Self> {
64 } else if lookahead.peek(kw::hide) {66 } else if lookahead.peek(kw::hide) {
65 input.parse::<kw::hide>()?;67 input.parse::<kw::hide>()?;
66 out.hide = true;68 out.hide = true;
67 } else if input.is_empty() {69 } else if lookahead.peek(kw::method) {
70 input.parse::<kw::method>()?;
71 out.method = true;
72 } else if input.is_empty() {
68 break;73 break;
69 } else {74 } else {
70 return Err(lookahead.error());75 return Err(lookahead.error());
134 }139 }
135140
136 fn expand_field(&self) -> Option<TokenStream> {141 fn expand_field(&self) -> Option<TokenStream> {
137 if self.is_option {142 if self.is_option || self.attr.method {
138 return None;143 return None;
139 }144 }
140 let name = self.name()?;145 let name = self.name()?;
256 } else {261 } else {
257 quote! {}262 quote! {}
258 };263 };
259 let value = if self.is_lazy {264 let value = if self.attr.method {
265 quote! {
266 out.method(__names[#name].clone(), value);
267 }
268 } else if self.is_lazy {
260 quote! {269 quote! {
261 out.field(__names[#name].clone())270 out.field(__names[#name].clone())
262 #hide271 #hide