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

difftreelog

refactor split TypedObj derives

oqrkzkryYaroslav Bolyukin2026-03-22parent: #bd50dd1.patch.diff
in: master

5 files changed

modifiedcrates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth
609 }609 }
610}610}
611611
612#[derive(Typed)]612#[derive(Typed, IntoUntyped)]
613pub struct KeyValue {613pub struct KeyValue {
614 key: IStr,614 key: IStr,
615 value: Thunk<Val>,615 value: Thunk<Val>,
modifiedcrates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth
22
3use jrsonnet_gcmodule::Trace;3use jrsonnet_gcmodule::Trace;
4use jrsonnet_interner::{IBytes, IStr};4use jrsonnet_interner::{IBytes, IStr};
5pub use jrsonnet_macros::Typed;
6use jrsonnet_types::{ComplexValType, ValType};5use jrsonnet_types::{ComplexValType, ValType};
76
8use crate::{7use crate::{
14 ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,13 ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,
15};14};
15
16#[doc(hidden)]
17pub mod __typed_macro_prelude {
18 pub use ::jrsonnet_evaluator::{
19 error::{ErrorKind, Result as JrResult},
20 typed::{
21 CheckType, ComplexValType, FromUntyped, IntoUntyped, ParseTypedObj, SerializeTypedObj,
22 Typed,
23 },
24 IStr, ObjValue, ObjValueBuilder, State, Val,
25 };
26}
27pub use jrsonnet_macros::{FromUntyped, IntoUntyped, Typed};
1628
17#[derive(Trace)]29#[derive(Trace)]
18struct ThunkFromUntyped<K: Trace>(PhantomData<fn() -> K>);30struct ThunkFromUntyped<K: Trace>(PhantomData<fn() -> K>);
49 }61 }
50}62}
5163
64pub trait ParseTypedObj: Typed {
65 fn parse(obj: &ObjValue) -> Result<Self>;
66}
52pub trait TypedObj: Typed {67pub trait SerializeTypedObj: Typed {
53 fn serialize(self, out: &mut ObjValueBuilder) -> Result<()>;68 fn serialize(self, out: &mut ObjValueBuilder) -> Result<()>;
54 fn parse(obj: &ObjValue) -> Result<Self>;
55 fn into_object(self) -> Result<ObjValue> {69 fn into_object(self) -> Result<ObjValue> {
56 let mut builder = ObjValueBuilder::new();70 let mut builder = ObjValueBuilder::new();
57 self.serialize(&mut builder)?;71 self.serialize(&mut builder)?;
modifiedcrates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth
13 LitStr, Meta, Pat, Path, PathArguments, Result, ReturnType, Token, Type,13 LitStr, Meta, Pat, Path, PathArguments, Result, ReturnType, Token, Type,
14};14};
1515
16use self::typed::derive_typed_inner;16use self::typed::{derive_from_untyped_inner, derive_into_untyped_inner, derive_typed_inner};
1717
18mod names;18mod names;
19mod typed;19mod typed;
451 Err(e) => e.to_compile_error().into(),451 Err(e) => e.to_compile_error().into(),
452 }452 }
453}453}
454#[proc_macro_derive(IntoUntyped, attributes(typed))]
455pub fn derive_into_untyped(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
456 let input = parse_macro_input!(item as DeriveInput);
457
458 match derive_into_untyped_inner(input) {
459 Ok(v) => v.into(),
460 Err(e) => e.to_compile_error().into(),
461 }
462}
463#[proc_macro_derive(FromUntyped, attributes(typed))]
464pub fn derive_from_untyped(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
465 let input = parse_macro_input!(item as DeriveInput);
466
467 match derive_from_untyped_inner(input) {
468 Ok(v) => v.into(),
469 Err(e) => e.to_compile_error().into(),
470 }
471}
454472
455struct FormatInput {473struct FormatInput {
456 formatting: LitStr,474 formatting: LitStr,
modifiedcrates/jrsonnet-macros/src/typed.rsdiffbeforeafterboth
287 }287 }
288}288}
289289
290pub fn derive_typed_inner(input: DeriveInput) -> Result<TokenStream> {
291 let syn::Data::Struct(data) = &input.data else {
292 return Err(Error::new(input.span(), "only structs supported"));
293 };
294
295 let ident = &input.ident;
296 let fields = data
297 .fields
298 .iter()
299 .map(TypedField::parse)
300 .collect::<Result<Vec<_>>>()?;
301
302 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
303
304 let fields = fields
305 .iter()
306 .filter_map(TypedField::expand_field)
307 .collect::<Vec<_>>();
308 Ok(quote! {
309 const _: () = {
310 use ::jrsonnet_evaluator::typed::__typed_macro_prelude::*;
311
312 impl #impl_generics Typed for #ident #ty_generics #where_clause {
313 const TYPE: &'static ComplexValType = &ComplexValType::ObjectRef(&[
314 #(#fields,)*
315 ]);
316 }
317 };
318 })
319}
320pub fn derive_into_untyped_inner(input: DeriveInput) -> Result<TokenStream> {
321 let syn::Data::Struct(data) = &input.data else {
322 return Err(Error::new(input.span(), "only structs supported"));
323 };
324
325 let ident = &input.ident;
326 let fields = data
327 .fields
328 .iter()
329 .map(TypedField::parse)
330 .collect::<Result<Vec<_>>>()?;
331
332 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
333
334 let capacity = fields.len();
335
336 let mut names = Names::default();
337
338 let fields_serialize = fields
339 .iter()
340 .map(|f| f.expand_serialize(&mut names))
341 .collect::<Vec<_>>();
342
343 let names_expanded = names.expand();
344 Ok(quote! {
345 const _: () = {
346 use ::jrsonnet_evaluator::typed::__typed_macro_prelude::*;
347
348 impl #impl_generics IntoUntyped for #ident #ty_generics #where_clause {
349 fn into_untyped(value: Self) -> JrResult<Val> {
350 let mut out = ObjValueBuilder::with_capacity(#capacity);
351 value.serialize(&mut out)?;
352 Ok(Val::Obj(out.build()))
353 }
354 }
355
356 #names_expanded
357
358 impl #impl_generics SerializeTypedObj for #ident #ty_generics #where_clause {
359 fn serialize(self, out: &mut ObjValueBuilder) -> JrResult<()> {
360 NAMES.with(|__names| {
361 #(#fields_serialize)*
362
363 Ok(())
364 })
365 }
366 }
367 };
368 })
369}
290pub fn derive_typed_inner(input: DeriveInput) -> Result<TokenStream> {370pub fn derive_from_untyped_inner(input: DeriveInput) -> Result<TokenStream> {
291 let syn::Data::Struct(data) = &input.data else {371 let syn::Data::Struct(data) = &input.data else {
292 return Err(Error::new(input.span(), "only structs supported"));372 return Err(Error::new(input.span(), "only structs supported"));
293 };373 };
301381
302 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();382 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
303
304 let capacity = fields.len();
305
306 let typed = {
307 let fields = fields
308 .iter()
309 .filter_map(TypedField::expand_field)
310 .collect::<Vec<_>>();
311 quote! {
312 impl #impl_generics Typed for #ident #ty_generics #where_clause {
313 const TYPE: &'static ComplexValType = &ComplexValType::ObjectRef(&[
314 #(#fields,)*
315 ]);
316 }
317
318 impl #impl_generics FromUntyped for #ident #ty_generics #where_clause {
319 fn from_untyped(value: Val) -> JrResult<Self> {
320 let obj = value.as_obj().expect("shape is correct");
321 Self::parse(&obj)
322 }
323 }
324
325 impl #impl_generics IntoUntyped for #ident #ty_generics #where_clause {
326 fn into_untyped(value: Self) -> JrResult<Val> {
327 let mut out = ObjValueBuilder::with_capacity(#capacity);
328 value.serialize(&mut out)?;
329 Ok(Val::Obj(out.build()))
330 }
331 }
332 }
333 };
334383
335 let mut names = Names::default();384 let mut names = Names::default();
336385
337 let fields_parse = fields386 let fields_parse = fields
338 .iter()387 .iter()
339 .map(|f| f.expand_parse(&mut names))388 .map(|f| f.expand_parse(&mut names))
340 .collect::<Vec<_>>();389 .collect::<Vec<_>>();
341 let fields_serialize = fields
342 .iter()
343 .map(|f| f.expand_serialize(&mut names))
344 .collect::<Vec<_>>();
345390
346 let names_expanded = names.expand();391 let names_expanded = names.expand();
347 Ok(quote! {392 Ok(quote! {
348 const _: () = {393 const _: () = {
349 use ::jrsonnet_evaluator::{394 use ::jrsonnet_evaluator::typed::__typed_macro_prelude::*;
350 typed::{ComplexValType, Typed, IntoUntyped, FromUntyped, TypedObj, CheckType},
351 Val, State,
352 error::{ErrorKind, Result as JrResult},
353 ObjValueBuilder, ObjValue, IStr,
354 };
355
356 #typed
357
358 #names_expanded
359395
360 impl #impl_generics TypedObj for #ident #ty_generics #where_clause {396 impl #impl_generics FromUntyped for #ident #ty_generics #where_clause {
361 fn serialize(self, out: &mut ObjValueBuilder) -> JrResult<()> {397 fn from_untyped(value: Val) -> JrResult<Self> {
362 NAMES.with(|__names| {398 let obj = value.as_obj().expect("shape is correct");
363 #(#fields_serialize)*399 Self::parse(&obj)
364
365 Ok(())
366 })
367 }400 }
401 }
402
403 #names_expanded
404
405 impl #impl_generics ParseTypedObj for #ident #ty_generics #where_clause {
368 fn parse(obj: &ObjValue) -> JrResult<Self> {406 fn parse(obj: &ObjValue) -> JrResult<Self> {
369 NAMES.with(|__names| Ok(Self {407 NAMES.with(|__names| Ok(Self {
370 #(#fields_parse)*408 #(#fields_parse)*
371 }))409 }))
372 }410 }
373 }411 }
374 };412 };
375 })413 })
376}414}
modifiedcrates/jrsonnet-stdlib/src/manifest/ini.rsdiffbeforeafterboth
82 Ok(())82 Ok(())
83}83}
8484
85#[derive(Typed)]85#[derive(Typed, FromUntyped)]
86struct IniObj {86struct IniObj {
87 main: Option<ObjValue>,87 main: Option<ObjValue>,
88 // TODO: Preserve section order?88 // TODO: Preserve section order?