From d3309b91d59e7fd37b9e01cf5ffbd87e41d18efe Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Mon, 25 Mar 2024 16:26:25 +0100 Subject: [PATCH] derive: Add skip option to ExtensionDispatch This patch adds a skip option to the ExtensionDispatch macro that makes it possible to ignore some fields. --- derive/examples/extension-dispatch.rs | 4 +++ derive/src/extension_dispatch.rs | 36 ++++++++++++++++----------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/derive/examples/extension-dispatch.rs b/derive/examples/extension-dispatch.rs index 256dfc13621..3915f7ba320 100644 --- a/derive/examples/extension-dispatch.rs +++ b/derive/examples/extension-dispatch.rs @@ -127,6 +127,10 @@ struct Dispatch { a_sample: (), b: backends::BBackend, + + #[allow(unused)] + #[dispatch(skip)] + other: String, } fn main() { diff --git a/derive/src/extension_dispatch.rs b/derive/src/extension_dispatch.rs index 09f073e28d9..5c30412d866 100644 --- a/derive/src/extension_dispatch.rs +++ b/derive/src/extension_dispatch.rs @@ -28,11 +28,12 @@ impl ExtensionDispatch { }; let dispatch_attrs = DispatchAttrs::new(&input)?; let extension_attrs = ExtensionAttrs::new(&input)?; - let raw_backends: Vec<_> = data_struct - .fields - .iter() - .map(RawBackend::new) - .collect::>()?; + let mut raw_backends = Vec::new(); + for field in &data_struct.fields { + if let Some(raw_backend) = RawBackend::new(field)? { + raw_backends.push(raw_backend); + } + } let mut backends = Vec::new(); let mut delegated_backends = Vec::new(); for raw_backend in raw_backends { @@ -204,38 +205,45 @@ struct RawBackend { } impl RawBackend { - fn new(field: &Field) -> Result { - let ident = field.ident.clone().ok_or_else(|| { - Error::new_spanned( - field, - "ExtensionDispatch can only be derived for a struct with named fields", - ) - })?; + fn new(field: &Field) -> Result> { let mut delegate_to = None; + let mut skip = false; for attr in util::get_attrs(&field.attrs, "dispatch") { attr.parse_nested_meta(|meta| { if meta.path.is_ident("delegate_to") { let s: LitStr = meta.value()?.parse()?; delegate_to = Some(s.parse()?); Ok(()) + } else if meta.path.is_ident("skip") { + skip = true; + Ok(()) } else { Err(meta.error("unsupported dispatch attribute")) } })?; } + if skip { + return Ok(None); + } + let ident = field.ident.clone().ok_or_else(|| { + Error::new_spanned( + field, + "ExtensionDispatch can only be derived for a struct with named fields", + ) + })?; let mut extensions = Vec::new(); for attr in util::get_attrs(&field.attrs, "extensions") { for s in attr.parse_args_with(Punctuated::::parse_terminated)? { extensions.push(s.parse()?); } } - Ok(Self { + Ok(Some(Self { id: util::to_camelcase(&ident), field: ident, ty: field.ty.clone(), delegate_to, extensions, - }) + })) } }