Skip to content

Commit 54b12d2

Browse files
Allow specification of lifetimes in mapping macros (#6)
* Lifetime tweaks * Clean up and add test
1 parent 79dc75c commit 54b12d2

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ members = [
33
"metastruct",
44
"metastruct_macro",
55
]
6+
resolver = "2"

metastruct_macro/src/mapping.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ pub(crate) fn generate_mapping_macro(
2929
quote! { ref }
3030
};
3131

32-
let mapping_function_types = selected_field_types
32+
let mapping_function_input_types = selected_field_types
3333
.iter()
3434
.map(|field_type| {
3535
if mapping_opts.mutable {
36-
quote! { &mut dyn FnMut(usize, &'_ mut #field_type) -> _ }
36+
quote! { mut #field_type }
3737
} else {
38-
quote! { &mut dyn FnMut(usize, &'_ #field_type) -> _ }
38+
quote! { #field_type }
3939
}
4040
})
4141
.collect::<Vec<_>>();
@@ -54,7 +54,7 @@ pub(crate) fn generate_mapping_macro(
5454
quote! {
5555
#[macro_export]
5656
macro_rules! #macro_name {
57-
($v:expr, $f:expr) => {
57+
(&$lifetime:tt _, $v:expr, $f:expr) => {
5858
match $v {
5959
#type_name {
6060
#(
@@ -64,13 +64,16 @@ pub(crate) fn generate_mapping_macro(
6464
} => {
6565
let mut __metastruct_i: usize = 0;
6666
#(
67-
let __metastruct_f: #mapping_function_types = &mut $f;
67+
let __metastruct_f: &mut dyn FnMut(usize, &$lifetime #mapping_function_input_types) -> _ = &mut $f;
6868
#function_call_exprs;
6969
__metastruct_i += 1;
7070
)*
7171
}
7272
}
73-
}
73+
};
74+
($v:expr, $f:expr) => {
75+
#macro_name!(&'_ _, $v, $f)
76+
};
7477
}
7578
}
7679
.into()

metastruct_macro/tests/lifetime.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use metastruct_macro::metastruct;
2+
3+
#[metastruct(mappings(map_foo_fields()))]
4+
struct Foo {
5+
x: u64,
6+
y: u16,
7+
z: u32,
8+
}
9+
10+
fn sum<'a>(total: &'a mut u64, foo: &'a Foo) {
11+
map_foo_fields!(&'a _, foo, |_, field| *total += *field as u64);
12+
}
13+
14+
#[test]
15+
fn reference_with_lifetime() {
16+
let foo = Foo { x: 1, y: 2, z: 3 };
17+
let mut total = 0;
18+
sum(&mut total, &foo);
19+
assert_eq!(total, 6);
20+
}

0 commit comments

Comments
 (0)