diff --git a/multi_index_map/benches/performance.rs b/multi_index_map/benches/performance.rs index 3e05128..b00d882 100644 --- a/multi_index_map/benches/performance.rs +++ b/multi_index_map/benches/performance.rs @@ -4,6 +4,7 @@ use multi_index_map::MultiIndexMap; #[derive(Hash, PartialEq, Eq, Clone, Debug)] struct TestNonPrimitiveType(u32); +#[allow(clippy::struct_field_names)] #[derive(MultiIndexMap, Debug, Clone)] #[multi_index_derive(Clone, Debug)] pub struct TestElementWithOnlyIndexedFields { @@ -17,12 +18,12 @@ pub struct TestElementWithOnlyIndexedFields { field_ordered_non_unique: u32, } -const BENCH_SIZES: &[u32] = &[100u32, 1000u32, 10000u32, 100000u32]; +const BENCH_SIZES: &[u32] = &[100u32, 1_000u32, 10_000u32, 100_000u32]; fn insert_benchmark(c: &mut Criterion) { fn inner(c: &mut Criterion, n: u32) { let mut map = black_box(MultiIndexTestElementWithOnlyIndexedFieldsMap::default()); - c.bench_function(&format!("insert_bench_{}", n), |b| { + c.bench_function(&format!("insert_bench_{n}"), |b| { b.iter(|| { for i in 0..n { map.insert(black_box(TestElementWithOnlyIndexedFields { @@ -33,7 +34,7 @@ fn insert_benchmark(c: &mut Criterion) { })); map.clear(); } - }) + }); }); } @@ -53,7 +54,7 @@ fn delete_by_hashed_unique_key_benchmark(c: &mut Criterion) { field_ordered_non_unique: i / 5, })); } - c.bench_function(&format!("delete_hashed_unique_key_bench_{}", n), |b| { + c.bench_function(&format!("delete_hashed_unique_key_bench_{n}"), |b| { b.iter(|| { let mut map_clone = black_box(map.clone()); for i in 0..n { @@ -62,7 +63,7 @@ fn delete_by_hashed_unique_key_benchmark(c: &mut Criterion) { .remove_by_field_hashed_unique(black_box(&TestNonPrimitiveType(i))), ); } - }) + }); }); } @@ -82,7 +83,7 @@ fn delete_by_hashed_non_unique_key_benchmark(c: &mut Criterion) { field_ordered_non_unique: i / 5, })); } - c.bench_function(&format!("delete_hashed_non_unique_key_bench_{}", n), |b| { + c.bench_function(&format!("delete_hashed_non_unique_key_bench_{n}"), |b| { b.iter(|| { let mut map_clone = black_box(map.clone()); for i in 0..10 { @@ -90,7 +91,7 @@ fn delete_by_hashed_non_unique_key_benchmark(c: &mut Criterion) { &TestNonPrimitiveType(42 + i % 5), ))); } - }) + }); }); } @@ -110,13 +111,13 @@ fn delete_by_ordered_unique_key_benchmark(c: &mut Criterion) { field_ordered_non_unique: i / 5, })); } - c.bench_function(&format!("delete_ordered_unique_key_bench_{}", n), |b| { + c.bench_function(&format!("delete_ordered_unique_key_bench_{n}"), |b| { b.iter(|| { let mut map_clone = black_box(map.clone()); for i in 0..n { black_box(map_clone.remove_by_field_ordered_unique(black_box(&i))); } - }) + }); }); } @@ -136,13 +137,13 @@ fn delete_by_ordered_non_unique_key_benchmark(c: &mut Criterion) { field_ordered_non_unique: i / 5, })); } - c.bench_function(&format!("delete_ordered_non_unique_key_bench_{}", n), |b| { + c.bench_function(&format!("delete_ordered_non_unique_key_bench_{n}"), |b| { b.iter(|| { let mut map_clone = black_box(map.clone()); for i in 0..n { black_box(map_clone.remove_by_field_ordered_non_unique(black_box(&(i / 5)))); } - }) + }); }); } @@ -163,7 +164,7 @@ fn modify_hashed_unique_key_by_hashed_unique_key_benchmark(c: &mut Criterion) { })); } c.bench_function( - &format!("modify_hashed_unique_key_by_hashed_unique_key_bench_{}", n), + &format!("modify_hashed_unique_key_by_hashed_unique_key_bench_{n}"), |b| { b.iter(|| { let mut map_clone = black_box(map.clone()); @@ -176,7 +177,7 @@ fn modify_hashed_unique_key_by_hashed_unique_key_benchmark(c: &mut Criterion) { }, )); } - }) + }); }, ); } @@ -199,8 +200,7 @@ fn modify_hashed_non_unique_key_by_hashed_unique_key_benchmark(c: &mut Criterion } c.bench_function( &format!( - "modify_hashed_non_unique_key_by_hashed_unique_key_bench_{}", - n + "modify_hashed_non_unique_key_by_hashed_unique_key_bench_{n}" ), |b| { b.iter(|| { @@ -215,7 +215,7 @@ fn modify_hashed_non_unique_key_by_hashed_unique_key_benchmark(c: &mut Criterion }, )); } - }) + }); }, ); } @@ -237,7 +237,7 @@ fn modify_ordered_unique_key_by_hashed_unique_key_benchmark(c: &mut Criterion) { })); } c.bench_function( - &format!("modify_ordered_unique_key_by_hashed_unique_key_bench_{}", n), + &format!("modify_ordered_unique_key_by_hashed_unique_key_bench_{n}"), |b| { b.iter(|| { let mut map_clone = black_box(map.clone()); @@ -249,7 +249,7 @@ fn modify_ordered_unique_key_by_hashed_unique_key_benchmark(c: &mut Criterion) { }, )); } - }) + }); }, ); } @@ -272,8 +272,7 @@ fn modify_ordered_non_unique_key_by_hashed_unique_key_benchmark(c: &mut Criterio } c.bench_function( &format!( - "modify_ordered_non_unique_key_by_hashed_unique_key_bench_{}", - n + "modify_ordered_non_unique_key_by_hashed_unique_key_bench_{n}" ), |b| { b.iter(|| { @@ -286,7 +285,7 @@ fn modify_ordered_non_unique_key_by_hashed_unique_key_benchmark(c: &mut Criterio }), )); } - }) + }); }, ); } @@ -308,7 +307,7 @@ fn modify_hashed_unique_key_by_ordered_unique_key_benchmark(c: &mut Criterion) { })); } c.bench_function( - &format!("modify_hashed_unique_key_by_ordered_unique_key_bench_{}", n), + &format!("modify_hashed_unique_key_by_ordered_unique_key_bench_{n}"), |b| { b.iter(|| { let mut map_clone = black_box(map.clone()); @@ -321,7 +320,7 @@ fn modify_hashed_unique_key_by_ordered_unique_key_benchmark(c: &mut Criterion) { }, )); } - }) + }); }, ); } @@ -344,8 +343,7 @@ fn modify_hashed_non_unique_key_by_ordered_unique_key_benchmark(c: &mut Criterio } c.bench_function( &format!( - "modify_hashed_non_unique_key_by_ordered_unique_key_bench_{}", - n + "modify_hashed_non_unique_key_by_ordered_unique_key_bench_{n}" ), |b| { b.iter(|| { @@ -360,7 +358,7 @@ fn modify_hashed_non_unique_key_by_ordered_unique_key_benchmark(c: &mut Criterio }, )); } - }) + }); }, ); } @@ -383,8 +381,7 @@ fn modify_ordered_unique_key_by_ordered_unique_key_benchmark(c: &mut Criterion) } c.bench_function( &format!( - "modify_ordered_unique_key_by_ordered_unique_key_bench_{}", - n + "modify_ordered_unique_key_by_ordered_unique_key_bench_{n}" ), |b| { b.iter(|| { @@ -397,7 +394,7 @@ fn modify_ordered_unique_key_by_ordered_unique_key_benchmark(c: &mut Criterion) }, )); } - }) + }); }, ); } @@ -420,8 +417,7 @@ fn modify_ordered_non_unique_key_by_ordered_unique_key_benchmark(c: &mut Criteri } c.bench_function( &format!( - "modify_ordered_non_unique_key_by_ordered_unique_key_bench_{}", - n + "modify_ordered_non_unique_key_by_ordered_unique_key_bench_{n}" ), |b| { b.iter(|| { @@ -434,7 +430,7 @@ fn modify_ordered_non_unique_key_by_ordered_unique_key_benchmark(c: &mut Criteri }, )); } - }) + }); }, ); } @@ -456,13 +452,13 @@ fn hashed_unique_key_iter_benchmark(c: &mut Criterion) { })); map.clear(); } - c.bench_function(&format!("hashed_unique_key_iter_bench_{}", n), |b| { + c.bench_function(&format!("hashed_unique_key_iter_bench_{n}"), |b| { b.iter(|| { let mut a = black_box(map.iter_by_field_hashed_unique()); for _ in 0..n { black_box(a.next()); } - }) + }); }); } @@ -483,13 +479,13 @@ fn hashed_non_unique_key_iter_benchmark(c: &mut Criterion) { })); map.clear(); } - c.bench_function(&format!("hashed_non_unique_key_iter_bench_{}", n), |b| { + c.bench_function(&format!("hashed_non_unique_key_iter_bench_{n}"), |b| { b.iter(|| { let mut a = black_box(map.iter_by_field_hashed_non_unique()); for _ in 0..n { black_box(a.next()); } - }) + }); }); } @@ -510,13 +506,13 @@ fn ordered_unique_key_iter_benchmark(c: &mut Criterion) { })); map.clear(); } - c.bench_function(&format!("ordered_unique_key_iter_bench_{}", n), |b| { + c.bench_function(&format!("ordered_unique_key_iter_bench_{n}"), |b| { b.iter(|| { let mut a = black_box(map.iter_by_field_ordered_unique()); for _ in 0..n { black_box(a.next()); } - }) + }); }); } @@ -537,13 +533,13 @@ fn ordered_non_unique_key_iter_benchmark(c: &mut Criterion) { })); map.clear(); } - c.bench_function(&format!("ordered_non_unique_key_iter_bench_{}", n), |b| { + c.bench_function(&format!("ordered_non_unique_key_iter_bench_{n}"), |b| { b.iter(|| { let mut a = black_box(map.iter_by_field_ordered_non_unique()); for _ in 0..n { black_box(a.next()); } - }) + }); }); } diff --git a/multi_index_map/examples/main.rs b/multi_index_map/examples/main.rs index 3f82e94..f30ec19 100644 --- a/multi_index_map/examples/main.rs +++ b/multi_index_map/examples/main.rs @@ -6,6 +6,7 @@ mod inner { #[derive(MultiIndexMap, Debug, Clone)] #[multi_index_derive(Clone, Debug)] pub(crate) struct Order { + #[allow(clippy::struct_field_names)] #[multi_index(hashed_unique)] pub(crate) order_id: u32, #[multi_index(ordered_unique)] @@ -16,39 +17,35 @@ mod inner { } } + + fn main() { let o1 = Order { order_id: 1, timestamp: 111, trader_name: "John".to_string(), - note: "".to_string(), + note: String::new(), }; let o2 = Order { order_id: 2, timestamp: 22, trader_name: "Tom".to_string(), - note: "".to_string(), + note: String::new(), }; - let mut map = MultiIndexOrderMap::default(); - - let _o1_ref: &Order = map.insert(o1); - let _o2_ref: &Order = map.try_insert(o2).unwrap(); - - // Set non-mutable, non mutating iter methods still work. - let map = map; + let map = [o1, o2].into_iter().collect::(); for o in map.iter_by_timestamp() { - println!("iter_by_timestamp: {o:?}") + println!("iter_by_timestamp: {o:?}"); } for o in map.iter_by_order_id() { - println!("iter_by_order_id: {o:?}") + println!("iter_by_order_id: {o:?}"); } - for (_, o) in map.iter() { - println!("iter: {o:?}") + for (_, o) in &map { + println!("iter: {o:?}"); } let o1_ref = map.get_by_order_id(&1).unwrap(); @@ -61,7 +58,7 @@ fn main() { let mut map = map; for (o,) in map.iter_mut() { - println!("iter_mut: {o:?}") + println!("iter_mut: {o:?}"); } let o1_ref = map @@ -81,7 +78,7 @@ fn main() { *note = "TestNote".to_string(); }) .unwrap(); - println!("Updated note of order {o1_ref:?}, to {:?}", o1_ref.note,); + println!("Updated note of order {o1_ref:?}, to {:?}", o1_ref.note); let (o1_note_ref,) = map.get_mut_by_order_id(&7).unwrap(); *o1_note_ref = "TestNoteUpdated".to_string(); @@ -92,13 +89,13 @@ fn main() { let toms_orders = map.remove_by_trader_name(&"Tom".to_string()); assert_eq!(toms_orders.len(), 2); - println!("Removed Tom's order by name: {toms_orders:?}",); + println!("Removed Tom's order by name: {toms_orders:?}"); let o3 = Order { order_id: 3, timestamp: 33, trader_name: "Jimbo".to_string(), - note: "".to_string(), + note: String::new(), }; map.insert(o3); diff --git a/multi_index_map/tests/derive_basic.rs b/multi_index_map/tests/derive_basic.rs index c6989cd..d876fa0 100644 --- a/multi_index_map/tests/derive_basic.rs +++ b/multi_index_map/tests/derive_basic.rs @@ -19,7 +19,7 @@ fn should_compile() { // check that formatting produces non empty strings assert!(!format!("{:?}", map._field1_index).is_empty()); assert!(!format!("{:?}", map._store).is_empty()); - assert!(!format!("{:?}", map).is_empty()); + assert!(!format!("{map:?}").is_empty()); let elem1 = TestElement { field1: TestNonPrimitiveType(42), @@ -27,7 +27,7 @@ fn should_compile() { }; map.insert(elem1); - let msg = format!("{:?}", map); + let msg = format!("{map:?}"); // check if indexed fields are present in debug output assert!(msg.contains("42")); diff --git a/multi_index_map/tests/get_and_modify_mut.rs b/multi_index_map/tests/get_and_modify_mut.rs index b8c49db..fe0f66c 100644 --- a/multi_index_map/tests/get_and_modify_mut.rs +++ b/multi_index_map/tests/get_and_modify_mut.rs @@ -31,7 +31,7 @@ fn test_non_unique_get_mut() { let mut_refs: Vec<(&mut usize,)> = map.get_mut_by_field1(&37); for (r,) in mut_refs { - *r *= *r + *r *= *r; } let refs: Vec<&TestElement> = map.get_by_field1(&37); @@ -60,7 +60,7 @@ fn test_non_unique_iter_mut() { } for (field2,) in map.iter_mut() { - *field2 *= *field2 + *field2 *= *field2; } let refs: Vec<&TestElement> = map.get_by_field1(&37); diff --git a/multi_index_map/tests/hashed_unique.rs b/multi_index_map/tests/hashed_unique.rs index 72bfc24..08390d9 100644 --- a/multi_index_map/tests/hashed_unique.rs +++ b/multi_index_map/tests/hashed_unique.rs @@ -10,6 +10,34 @@ struct TestElement { field2: String, } +#[test] +fn test_collect() { + let elements = vec![ + TestElement { + field1: TestNonPrimitiveType(42), + field2: "ElementOne".to_string(), + }, + TestElement { + field1: TestNonPrimitiveType(43), + field2: "ElementTwo".to_string(), + }, + TestElement { + field1: TestNonPrimitiveType(42), + field2: "The first element always wins any uniqueness conflict".to_string(), + }, + ]; + + let map: MultiIndexTestElementMap = elements.into_iter().collect(); + + let elem1_ref = map.get_by_field1(&TestNonPrimitiveType(42)).unwrap(); + assert_eq!(elem1_ref.field1.0, 42); + assert_eq!(elem1_ref.field2, "ElementOne"); + let elem2_ref = map.get_by_field1(&TestNonPrimitiveType(43)).unwrap(); + assert_eq!(elem2_ref.field1.0, 43); + assert_eq!(elem2_ref.field2, "ElementTwo"); + assert_eq!(map.len(), 2); +} + #[test] fn test_insert_and_get() { let mut map = MultiIndexTestElementMap::default(); @@ -56,6 +84,7 @@ fn test_insert_and_remove_by_field1() { assert!(map.is_empty()); } +#[allow(deprecated)] #[test] fn test_unsafe_mutate_by_field1() { let mut map = MultiIndexTestElementMap::default(); @@ -90,7 +119,7 @@ fn test_modify_by_field1() { let elem1_ref = map .modify_by_field1(&TestNonPrimitiveType(42), |test_elem| { - test_elem.field1 = TestNonPrimitiveType(44) + test_elem.field1 = TestNonPrimitiveType(44); }) .unwrap(); @@ -137,7 +166,7 @@ fn test_modify_violate_uniqueness() { let res = std::panic::catch_unwind(move || { map.modify_by_field1(&TestNonPrimitiveType(43), |e| { - e.field1 = TestNonPrimitiveType(42) + e.field1 = TestNonPrimitiveType(42); }); }); diff --git a/multi_index_map/tests/non_unique_holes.rs b/multi_index_map/tests/non_unique_holes.rs index 8015a94..2006f43 100644 --- a/multi_index_map/tests/non_unique_holes.rs +++ b/multi_index_map/tests/non_unique_holes.rs @@ -17,8 +17,8 @@ struct Entry { fn make_with_holes() -> MultiIndexEntryMap { let mut map = MultiIndexEntryMap::default(); - for id in 0..6usize { - map.insert(Entry { group: 1, value: id as i32, id }); + for id in 0..6u16 { + map.insert(Entry { group: 1, value: id.into(), id: id.into() }); } // Create holes at indices 0 and 1 assert!(map.remove_by_id(&0).is_some()); @@ -81,7 +81,7 @@ fn non_unique_get_mut_after_holes_aliasing_safe() { // Obtain multiple &mut safely via a single iter_mut()-driven traversal let mut_refs: Vec<(&mut i32,)> = map.get_mut_by_group(&1); assert_eq!(mut_refs.len(), 4); - for (v,) in mut_refs.into_iter() { + for (v,) in mut_refs { *v += 100; } diff --git a/multi_index_map/tests/ordered_unique.rs b/multi_index_map/tests/ordered_unique.rs index e50082d..a28c5bf 100644 --- a/multi_index_map/tests/ordered_unique.rs +++ b/multi_index_map/tests/ordered_unique.rs @@ -79,7 +79,7 @@ fn test_modify_by_field1() { assert_eq!(&elem_at_index_2.field2, "ElementTwo"); } map.modify_by_field1(&TestNonPrimitiveType(42), |test_elem| { - test_elem.field1 = TestNonPrimitiveType(44) + test_elem.field1 = TestNonPrimitiveType(44); }); let mut field_1_iter = map.iter_by_field1(); @@ -130,7 +130,7 @@ fn test_modify_violate_uniqueness() { let res = std::panic::catch_unwind(move || { map.modify_by_field1(&TestNonPrimitiveType(43), |e| { - e.field1 = TestNonPrimitiveType(42) + e.field1 = TestNonPrimitiveType(42); }); }); diff --git a/multi_index_map/tests/update.rs b/multi_index_map/tests/update.rs index aa59346..0f6e6d9 100644 --- a/multi_index_map/tests/update.rs +++ b/multi_index_map/tests/update.rs @@ -20,7 +20,7 @@ fn test_non_unique_update() { if i % 2 == 0 { map.insert(TestElement { field1: 42, - field2: i as f64, + field2: f64::from(i), field3: i, field4: i.to_string(), field5: "42".to_string(), @@ -28,7 +28,7 @@ fn test_non_unique_update() { } else { map.insert(TestElement { field1: 37, - field2: i as f64, + field2: f64::from(i), field3: i, field4: i.to_string(), field5: "37".to_string(), @@ -38,9 +38,9 @@ fn test_non_unique_update() { let refs = map.update_by_field1(&37, |field2, field4| { *field2 = 99.0; - *field4 = "NinetyNine".to_string() + *field4 = "NinetyNine".to_string(); }); - for r in refs.iter() { + for r in &refs { assert_eq!(r.field2, 99.0); assert_eq!(r.field4, "NinetyNine"); } @@ -59,7 +59,7 @@ fn test_non_unique_update_borrow() { if i % 2 == 0 { map.insert(TestElement { field1: 42, - field2: i as f64, + field2: f64::from(i), field3: i, field4: i.to_string(), field5: "42".to_string(), @@ -67,7 +67,7 @@ fn test_non_unique_update_borrow() { } else { map.insert(TestElement { field1: 37, - field2: i as f64, + field2: f64::from(i), field3: i, field4: i.to_string(), field5: "37".to_string(), @@ -77,9 +77,9 @@ fn test_non_unique_update_borrow() { let refs = map.update_by_field5("37", |field2, field4| { *field2 = 99.0; - *field4 = "NinetyNine".to_string() + *field4 = "NinetyNine".to_string(); }); - for r in refs.iter() { + for r in &refs { assert_eq!(r.field2, 99.0); assert_eq!(r.field4, "NinetyNine"); } @@ -98,7 +98,7 @@ fn test_unique_update() { if i % 2 == 0 { map.insert(TestElement { field1: 42, - field2: i as f64, + field2: f64::from(i), field3: i, field4: i.to_string(), field5: "42".to_string(), @@ -106,7 +106,7 @@ fn test_unique_update() { } else { map.insert(TestElement { field1: 37, - field2: i as f64, + field2: f64::from(i), field3: i, field4: i.to_string(), field5: "37".to_string(), @@ -116,7 +116,7 @@ fn test_unique_update() { let elem = map.update_by_field3(&0, |field2, field4| { *field2 = 99.0; - *field4 = "NinetyNine".to_string() + *field4 = "NinetyNine".to_string(); }); assert_eq!( diff --git a/multi_index_map_derive/src/generators.rs b/multi_index_map_derive/src/generators.rs index 9107308..95dedcc 100644 --- a/multi_index_map_derive/src/generators.rs +++ b/multi_index_map_derive/src/generators.rs @@ -1,5 +1,5 @@ use ::quote::{format_ident, quote}; -use ::syn::{Field, Visibility}; +use ::syn::{Field, Visibility, parse_quote}; use proc_macro2::Ident; use syn::{Generics, Type}; @@ -1009,6 +1009,17 @@ pub(crate) fn generate_expanded( let (impls, types, where_clause) = generics.split_for_impl(); let (_, iter_types, _) = iter_generics.split_for_impl(); + let foreign_iter_type = Ident::new("__ForeignIter", proc_macro2::Span::call_site()); + + let mut generics_with_iterator_lifetime; + + let impls_with_iterator_lifetime = { + generics_with_iterator_lifetime = generics.clone(); + generics_with_iterator_lifetime.params.push(parse_quote!('__mim_iter_lifetime)); + let (impls_with_iterator_lifetime, _, _) = generics_with_iterator_lifetime.split_for_impl(); + impls_with_iterator_lifetime + }; + quote! { #(#[#derives])* #element_vis struct #map_name #impls { @@ -1096,6 +1107,30 @@ pub(crate) fn generate_expanded( #iter_mut + impl #impls_with_iterator_lifetime IntoIterator for &'__mim_iter_lifetime #map_name #types { + type Item = (usize, &'__mim_iter_lifetime #element_name #types); + type IntoIter = ::multi_index_map::slab::Iter<'__mim_iter_lifetime, #element_name #types>; + fn into_iter(self) -> Self::IntoIter { + self.iter() + } + } + + /// Build a #map_name from any IntoIterator of elements. + /// Among any sets of duplicate elements, "duplicate" referring to any unique index or indices, + /// the _first_ such element silently wins the conflict, + /// in contrast to [`std::collections::HashMap`] or [`std::collections::BTreeMap`] + /// who silently keep the _last_ duplicate elements. + impl #impls FromIterator<#element_name #types> for #map_name #types #where_clause { + fn from_iter<#foreign_iter_type: IntoIterator>(iter: #foreign_iter_type) -> Self { + let mut iter = iter.into_iter(); + let mut this = Self::with_capacity(iter.size_hint().0); + iter.for_each(|item| { + let _ = this.try_insert(item); + }); + this + } + } + #(#iterators)* } diff --git a/multi_index_map_derive/src/index_attributes.rs b/multi_index_map_derive/src/index_attributes.rs index a86afcd..6def162 100644 --- a/multi_index_map_derive/src/index_attributes.rs +++ b/multi_index_map_derive/src/index_attributes.rs @@ -23,29 +23,24 @@ pub(crate) enum Uniqueness { // Get the Ordering and Uniqueness for a given field attribute. pub(crate) fn get_index_kind(f: &Field) -> Option<(Ordering, Uniqueness)> { - for attr in f.attrs.iter() { + let mut ident_buf = String::new(); + for attr in &f.attrs { if attr.path.is_ident("multi_index") { - let meta_list = match attr.parse_meta() { - Ok(syn::Meta::List(l)) => l, - _ => return None, - }; - let nested = meta_list.nested.first()?; - let nested_path = match nested { - syn::NestedMeta::Meta(syn::Meta::Path(p)) => p, - _ => return None, - }; - - if nested_path.is_ident("hashed_unique") { - return Some((Ordering::Hashed, Uniqueness::Unique)); - } else if nested_path.is_ident("ordered_unique") { - return Some((Ordering::Ordered, Uniqueness::Unique)); - } else if nested_path.is_ident("hashed_non_unique") { - return Some((Ordering::Hashed, Uniqueness::NonUnique)); - } else if nested_path.is_ident("ordered_non_unique") { - return Some((Ordering::Ordered, Uniqueness::NonUnique)); - } else { - emit_error!(nested_path.span(), "Invalid multi_index attribute, should be one of [hashed_unique, ordered_unique, hashed_non_unique, ordered_non_unique]"); - return None; + return { + let Ok(syn::Meta::List(meta_list)) = attr.parse_meta() else { return None }; + let nested = meta_list.nested.first()?; + let syn::NestedMeta::Meta(syn::Meta::Path(nested_path)) = nested else { return None }; + + match nested_path.get_ident().map(|i| { ident_buf = i.to_string(); &*ident_buf }) { + Some("hashed_unique") => Some((Ordering::Hashed, Uniqueness::Unique)), + Some("ordered_unique") => Some((Ordering::Ordered, Uniqueness::Unique)), + Some("hashed_non_unique") => Some((Ordering::Hashed, Uniqueness::NonUnique)), + Some("ordered_non_unique") => Some((Ordering::Ordered, Uniqueness::NonUnique)), + _ => { + emit_error!(nested_path.span(), "Invalid multi_index attribute, should be one of [hashed_unique, ordered_unique, hashed_non_unique, ordered_non_unique]"); + None + } + } } } } @@ -85,29 +80,25 @@ impl ExtraAttributes { )))]), }); - self.derives.push(derive) + self.derives.push(derive); } } pub(crate) fn get_extra_attributes(f: &DeriveInput) -> ExtraAttributes { let mut extra_attrs = ExtraAttributes::default(); - for attr in f.attrs.iter() { + for attr in &f.attrs { if attr.path.is_ident("multi_index_derive") { - let meta_list = match attr.parse_meta() { - Ok(syn::Meta::List(l)) => l, - _ => break, + let Ok(syn::Meta::List(meta_list)) = attr.parse_meta() else { + break }; - for nested in meta_list.nested.iter() { - let nested_path = match nested { - syn::NestedMeta::Meta(syn::Meta::Path(p)) => p, - _ => { - emit_error!( - nested.span(), - "Invalid multi_index_derive attribute, should be a deriveable trait, eg. Clone, Debug" - ); - continue; - } + for nested in &meta_list.nested { + let syn::NestedMeta::Meta(syn::Meta::Path(nested_path)) = nested else { + emit_error!( + nested.span(), + "Invalid multi_index_derive attribute, should be a deriveable trait, eg. Clone, Debug" + ); + continue; }; let Some(ident) = nested_path.get_ident() else { @@ -119,20 +110,16 @@ pub(crate) fn get_extra_attributes(f: &DeriveInput) -> ExtraAttributes { } if attr.path.is_ident("multi_index_hash") { - let meta_list = match attr.parse_meta() { - Ok(syn::Meta::List(l)) => l, - _ => break, + let Ok(syn::Meta::List(meta_list)) = attr.parse_meta() else { + break }; - for nested in meta_list.nested.iter() { - let nested_path = match nested { - syn::NestedMeta::Meta(syn::Meta::Path(p)) => p, - _ => { - emit_error!( - nested.span(), - "Invalid multi_index_hash attribute, should be a struct implementing BuildHasher eg. FxBuildHasher" - ); - continue; - } + for nested in &meta_list.nested { + let syn::NestedMeta::Meta(syn::Meta::Path(nested_path)) = nested else { + emit_error!( + nested.span(), + "Invalid multi_index_hash attribute, should be a struct implementing BuildHasher eg. FxBuildHasher" + ); + continue; }; extra_attrs.hasher = nested_path.clone(); diff --git a/multi_index_map_derive/src/lib.rs b/multi_index_map_derive/src/lib.rs index efb63ac..b7ea83b 100644 --- a/multi_index_map_derive/src/lib.rs +++ b/multi_index_map_derive/src/lib.rs @@ -29,11 +29,10 @@ pub fn multi_index_map(input: proc_macro::TokenStream) -> proc_macro::TokenStrea // Verify the struct fields are named fields, // otherwise throw an error as we do not support Unnamed or Unit structs. - let named_fields = match fields { - syn::Fields::Named(f) => f, - _ => abort_call_site!( + let syn::Fields::Named(named_fields) = fields else { + abort_call_site!( "Struct fields must be named, unnamed tuple structs and unit structs are not supported" - ), + ) }; // Filter out all the fields that do not have a multi_index attribute,