difftreelog
refactor split TypedObj derives
in: master
5 files changed
crates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/arr/spec.rs
+++ b/crates/jrsonnet-evaluator/src/arr/spec.rs
@@ -609,7 +609,7 @@
}
}
-#[derive(Typed)]
+#[derive(Typed, IntoUntyped)]
pub struct KeyValue {
key: IStr,
value: Thunk<Val>,
crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth223use 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};768use crate::{7use crate::{14 ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,13 ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,15};14};1516#[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};162817#[derive(Trace)]29#[derive(Trace)]18struct ThunkFromUntyped<K: Trace>(PhantomData<fn() -> K>);30struct ThunkFromUntyped<K: Trace>(PhantomData<fn() -> K>);49 }61 }50}62}516364pub 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)?;crates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -13,7 +13,7 @@
LitStr, Meta, Pat, Path, PathArguments, Result, ReturnType, Token, Type,
};
-use self::typed::derive_typed_inner;
+use self::typed::{derive_from_untyped_inner, derive_into_untyped_inner, derive_typed_inner};
mod names;
mod typed;
@@ -451,6 +451,24 @@
Err(e) => e.to_compile_error().into(),
}
}
+#[proc_macro_derive(IntoUntyped, attributes(typed))]
+pub fn derive_into_untyped(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
+ let input = parse_macro_input!(item as DeriveInput);
+
+ match derive_into_untyped_inner(input) {
+ Ok(v) => v.into(),
+ Err(e) => e.to_compile_error().into(),
+ }
+}
+#[proc_macro_derive(FromUntyped, attributes(typed))]
+pub fn derive_from_untyped(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
+ let input = parse_macro_input!(item as DeriveInput);
+
+ match derive_from_untyped_inner(input) {
+ Ok(v) => v.into(),
+ Err(e) => e.to_compile_error().into(),
+ }
+}
struct FormatInput {
formatting: LitStr,
crates/jrsonnet-macros/src/typed.rsdiffbeforeafterboth--- a/crates/jrsonnet-macros/src/typed.rs
+++ b/crates/jrsonnet-macros/src/typed.rs
@@ -301,26 +301,49 @@
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
- let capacity = fields.len();
+ let fields = fields
+ .iter()
+ .filter_map(TypedField::expand_field)
+ .collect::<Vec<_>>();
+ Ok(quote! {
+ const _: () = {
+ use ::jrsonnet_evaluator::typed::__typed_macro_prelude::*;
- let typed = {
- let fields = fields
- .iter()
- .filter_map(TypedField::expand_field)
- .collect::<Vec<_>>();
- quote! {
impl #impl_generics Typed for #ident #ty_generics #where_clause {
const TYPE: &'static ComplexValType = &ComplexValType::ObjectRef(&[
#(#fields,)*
]);
}
+ };
+ })
+}
+pub fn derive_into_untyped_inner(input: DeriveInput) -> Result<TokenStream> {
+ let syn::Data::Struct(data) = &input.data else {
+ return Err(Error::new(input.span(), "only structs supported"));
+ };
+
+ let ident = &input.ident;
+ let fields = data
+ .fields
+ .iter()
+ .map(TypedField::parse)
+ .collect::<Result<Vec<_>>>()?;
+
+ let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+
+ let capacity = fields.len();
+
+ let mut names = Names::default();
+
+ let fields_serialize = fields
+ .iter()
+ .map(|f| f.expand_serialize(&mut names))
+ .collect::<Vec<_>>();
- impl #impl_generics FromUntyped for #ident #ty_generics #where_clause {
- fn from_untyped(value: Val) -> JrResult<Self> {
- let obj = value.as_obj().expect("shape is correct");
- Self::parse(&obj)
- }
- }
+ let names_expanded = names.expand();
+ Ok(quote! {
+ const _: () = {
+ use ::jrsonnet_evaluator::typed::__typed_macro_prelude::*;
impl #impl_generics IntoUntyped for #ident #ty_generics #where_clause {
fn into_untyped(value: Self) -> JrResult<Val> {
@@ -329,42 +352,57 @@
Ok(Val::Obj(out.build()))
}
}
- }
+
+ #names_expanded
+
+ impl #impl_generics SerializeTypedObj for #ident #ty_generics #where_clause {
+ fn serialize(self, out: &mut ObjValueBuilder) -> JrResult<()> {
+ NAMES.with(|__names| {
+ #(#fields_serialize)*
+
+ Ok(())
+ })
+ }
+ }
+ };
+ })
+}
+pub fn derive_from_untyped_inner(input: DeriveInput) -> Result<TokenStream> {
+ let syn::Data::Struct(data) = &input.data else {
+ return Err(Error::new(input.span(), "only structs supported"));
};
+ let ident = &input.ident;
+ let fields = data
+ .fields
+ .iter()
+ .map(TypedField::parse)
+ .collect::<Result<Vec<_>>>()?;
+
+ let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+
let mut names = Names::default();
let fields_parse = fields
.iter()
.map(|f| f.expand_parse(&mut names))
- .collect::<Vec<_>>();
- let fields_serialize = fields
- .iter()
- .map(|f| f.expand_serialize(&mut names))
.collect::<Vec<_>>();
let names_expanded = names.expand();
Ok(quote! {
const _: () = {
- use ::jrsonnet_evaluator::{
- typed::{ComplexValType, Typed, IntoUntyped, FromUntyped, TypedObj, CheckType},
- Val, State,
- error::{ErrorKind, Result as JrResult},
- ObjValueBuilder, ObjValue, IStr,
- };
+ use ::jrsonnet_evaluator::typed::__typed_macro_prelude::*;
- #typed
+ impl #impl_generics FromUntyped for #ident #ty_generics #where_clause {
+ fn from_untyped(value: Val) -> JrResult<Self> {
+ let obj = value.as_obj().expect("shape is correct");
+ Self::parse(&obj)
+ }
+ }
#names_expanded
- impl #impl_generics TypedObj for #ident #ty_generics #where_clause {
- fn serialize(self, out: &mut ObjValueBuilder) -> JrResult<()> {
- NAMES.with(|__names| {
- #(#fields_serialize)*
-
- Ok(())
- })
- }
+ impl #impl_generics ParseTypedObj for #ident #ty_generics #where_clause {
fn parse(obj: &ObjValue) -> JrResult<Self> {
NAMES.with(|__names| Ok(Self {
#(#fields_parse)*
crates/jrsonnet-stdlib/src/manifest/ini.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/manifest/ini.rs
+++ b/crates/jrsonnet-stdlib/src/manifest/ini.rs
@@ -82,7 +82,7 @@
Ok(())
}
-#[derive(Typed)]
+#[derive(Typed, FromUntyped)]
struct IniObj {
main: Option<ObjValue>,
// TODO: Preserve section order?