1#![warn(missing_docs)]
10#![warn(clippy::missing_errors_doc)]
11#![warn(clippy::missing_panics_doc)]
12
13use proc_macro::TokenStream;
16use quote::{quote, ToTokens};
17use syn::{
18 parse2, parse_macro_input, punctuated::Punctuated, AngleBracketedGenericArguments, DeriveInput,
19};
20
21fn get_names(ty_generics_token_stream: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
23 if ty_generics_token_stream.is_empty() {
24 proc_macro2::TokenStream::new()
25 } else {
26 let parsed_args: AngleBracketedGenericArguments =
27 parse2(ty_generics_token_stream)
28 .expect("Failed to parse ty_generics into AngleBracketedGenericArguments. This indicates an unexpected structure in the generic parameters.");
29
30 parsed_args.args.into_token_stream()
31 }
32}
33
34fn extract_additional_bounds(
36 input: &DeriveInput,
37 attr_name: &str,
38) -> Vec<proc_macro2::TokenStream> {
39 let mut additional_bounds = Vec::new();
40 for attr in &input.attrs {
41 if attr.path().is_ident(attr_name) {
42 attr.parse_nested_meta(|meta| {
43 if meta.path.is_ident("bound") {
44 let bound: syn::LitStr = meta.value()?.parse()?;
45 let bound_tokens: proc_macro2::TokenStream =
46 bound.value().parse().expect("Failed to parse bound");
47 additional_bounds.push(bound_tokens);
48 }
49 Ok(())
50 })
51 .expect("Failed to parse attribute {attr_name}");
52 }
53 }
54 additional_bounds
55}
56
57fn add_bounds_to_where_clause(
59 generics: &mut syn::Generics,
60 additional_bounds: Vec<proc_macro2::TokenStream>,
61) {
62 if !additional_bounds.is_empty() {
63 let where_clause = generics.make_where_clause();
64 for bound in additional_bounds {
65 let predicate: syn::WherePredicate =
66 syn::parse2(bound).expect("Invalid where predicate");
67 where_clause.predicates.push(predicate);
68 }
69 }
70}
71
72fn get_params_without_defaults(
73 generics: &syn::Generics,
74) -> Punctuated<syn::GenericParam, syn::token::Comma> {
75 let mut params = generics.params.clone();
77 params.iter_mut().for_each(|param| match param {
78 syn::GenericParam::Type(ty_param) => {
79 ty_param.default = None;
80 }
81 syn::GenericParam::Const(const_param) => {
82 const_param.default = None;
83 }
84 _ => {}
85 });
86 params
87}
88
89#[proc_macro_derive(Subslices, attributes(value_traits_subslices))]
110pub fn subslices(input: TokenStream) -> TokenStream {
111 let mut input = parse_macro_input!(input as DeriveInput);
112
113 let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices");
115 add_bounds_to_where_clause(&mut input.generics, additional_bounds);
116
117 let input_ident = input.ident;
118 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
119 let params = get_params_without_defaults(&input.generics);
120 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
121
122 let names = get_names(ty_generics_token_stream);
123 let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
124 let mut res = quote! {
125 #[automatically_derived]
126 pub struct #subslice_impl<'__subslice_impl, #params> {
127 slice: &'__subslice_impl #input_ident #ty_generics,
128 range: ::core::ops::Range<usize>,
129 }
130
131 #[automatically_derived]
132 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
133 type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
134
135 #[inline]
136 fn len(&self) -> usize {
137 self.range.len()
138 }
139 }
140
141 #[automatically_derived]
142 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueGet for #subslice_impl<'__subslice_impl, #names> #where_clause {
143 unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
144 self.slice.get_value_unchecked(index + self.range.start)
145 }
146 }
147
148 #[automatically_derived]
149 impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl<'__subslice_impl, #names> #where_clause {
150 type Subslice = #subslice_impl<'__subslice_gat, #names>;
151 }
152
153 #[automatically_derived]
154 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_impl> for #input_ident #ty_generics #where_clause {
155 type Subslice = #subslice_impl<'__subslice_impl, #names>;
156 }
157 };
158
159 for range_type in [
160 quote! { core::ops::Range<usize> },
161 quote! { core::ops::RangeFrom<usize> },
162 quote! { core::ops::RangeToInclusive<usize> },
163 quote! { core::ops::RangeFull },
164 quote! { core::ops::RangeInclusive<usize> },
165 quote! { core::ops::RangeTo<usize> },
166 ] {
167 res.extend(quote! {
168 #[automatically_derived]
169 impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<#range_type> for #input_ident #ty_generics #where_clause {
170 unsafe fn get_subslice_unchecked(
171 &self,
172 range: #range_type,
173 ) -> ::value_traits::slices::Subslice<'_, Self> {
174 #subslice_impl {
175 slice: &self,
176 range: ::value_traits::slices::ComposeRange::compose(&range, 0..self.len()),
177 }
178 }
179 }
180 #[automatically_derived]
181 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
182 for #subslice_impl<'__subslice_impl, #names> #where_clause
183 {
184 unsafe fn get_subslice_unchecked(
185 &self,
186 range: #range_type,
187 ) -> ::value_traits::slices::Subslice<'_, Self> {
188 #subslice_impl {
189 slice: self.slice,
190 range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
191 }
192 }
193 }
194 });
195 }
196
197 res.into()
198}
199
200#[proc_macro_derive(SubslicesMut, attributes(value_traits_subslices_mut))]
231pub fn subslices_mut(input: TokenStream) -> TokenStream {
232 let mut input = parse_macro_input!(input as DeriveInput);
233
234 let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices_mut");
236 add_bounds_to_where_clause(&mut input.generics, additional_bounds);
237
238 let input_ident = input.ident;
239 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
240 let params = get_params_without_defaults(&input.generics);
241 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
242
243 let names = get_names(ty_generics_token_stream);
244 let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
245 let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
246 let mut res = quote! {
247 #[automatically_derived]
248 pub struct #subslice_impl_mut<'__subslice_impl, #params> {
249 slice: &'__subslice_impl mut #input_ident #ty_generics,
250 range: ::core::ops::Range<usize>,
251 }
252
253 #[automatically_derived]
254 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
255 type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
256
257 #[inline]
258 fn len(&self) -> usize {
259 self.range.len()
260 }
261 }
262
263 #[automatically_derived]
264 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueGet for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
265 unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
266 self.slice.get_value_unchecked(index + self.range.start)
267 }
268 }
269
270 #[automatically_derived]
271 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSet for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
272 unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
273 self.slice.set_value_unchecked(index + self.range.start, value)
274 }
275 }
276
277 #[automatically_derived]
278 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueRepl for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
279 unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
280 self.slice.replace_value_unchecked(index + self.range.start, value)
281 }
282 }
283
284 #[automatically_derived]
285 impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
286 type Subslice = #subslice_impl<'__subslice_gat, #names>;
287 }
288
289 #[automatically_derived]
290 impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
291 type SubsliceMut = #subslice_impl_mut<'__subslice_gat, #names>;
292 }
293
294 #[automatically_derived]
295 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_impl> for #input_ident #ty_generics #where_clause {
296 type SubsliceMut = #subslice_impl_mut<'__subslice_impl, #names>;
297 }
298
299 };
300
301 for range_type in [
302 quote! { ::core::ops::Range<usize> },
303 quote! { ::core::ops::RangeFrom<usize> },
304 quote! { ::core::ops::RangeToInclusive<usize> },
305 quote! { ::core::ops::RangeFull },
306 quote! { ::core::ops::RangeInclusive<usize> },
307 quote! { ::core::ops::RangeTo<usize> },
308 ] {
309 res.extend(quote!{
311 #[automatically_derived]
312 impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type> for #input_ident #ty_generics #where_clause {
313 unsafe fn get_subslice_unchecked_mut(
314 &mut self,
315 range: #range_type,
316 ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
317 let len = self.len();
318 #subslice_impl_mut {
319 slice: self,
320 range: ::value_traits::slices::ComposeRange::compose(&range, 0..len),
321 }
322 }
323 }
324 #[automatically_derived]
325 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
326 for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
327 {
328 unsafe fn get_subslice_unchecked(
329 &self,
330 range: #range_type,
331 ) -> ::value_traits::slices::Subslice<'_, Self> {
332 #subslice_impl {
333 slice: &*self.slice,
334 range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
335 }
336 }
337 }
338 #[automatically_derived]
339 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type>
340 for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
341 {
342 unsafe fn get_subslice_unchecked_mut(
343 &mut self,
344 range: #range_type,
345 ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
346 #subslice_impl_mut {
347 slice: self.slice,
348 range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
349 }
350 }
351 }
352 });
353 }
354
355 res.into()
356}
357
358#[proc_macro_derive(Iterators, attributes(value_traits_iterators))]
384pub fn iterators(input: TokenStream) -> TokenStream {
385 let mut input = parse_macro_input!(input as DeriveInput);
386
387 let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators");
389 add_bounds_to_where_clause(&mut input.generics, additional_bounds);
390
391 let input_ident = input.ident;
392 input.generics.make_where_clause();
393 let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
394 let params = get_params_without_defaults(&input.generics);
395 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
396
397 let names = get_names(ty_generics_token_stream);
398 let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
399 let iter = quote::format_ident!("{}Iter", input_ident);
400 quote! {
401 #[automatically_derived]
402 pub struct #iter<'__iter_ref, #params> {
403 subslice: &'__iter_ref #input_ident #ty_generics,
404 range: ::core::ops::Range<usize>,
405 }
406
407 #[automatically_derived]
408 impl<'__iter_ref, #params> #iter<'__iter_ref, #names> #where_clause {
409 pub fn new(subslice: &'__iter_ref #input_ident #ty_generics) -> Self {
410 let len = subslice.len();
411 Self {
412 subslice,
413 range: 0..len,
414 }
415 }
416 pub fn new_with_range(subslice: &'__iter_ref #input_ident #ty_generics, range: ::core::ops::Range<usize>) -> Self {
417 Self {
418 subslice,
419 range,
420 }
421 }
422 }
423
424 #[automatically_derived]
454 impl<'__iter_ref, #params> ::core::iter::Iterator for #iter<'__iter_ref, #names> #where_clause {
459 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
460
461 #[inline]
462 fn next(&mut self) -> Option<Self::Item> {
463 if self.range.is_empty() {
464 return ::core::option::Option::None;
465 }
466 let value = unsafe { self.subslice.get_value_unchecked(self.range.start) };
467 self.range.start += 1;
468 ::core::option::Option::Some(value)
469 }
470
471 #[inline]
474 fn nth(&mut self, n: usize) -> Option<Self::Item> {
475 if n >= self.range.end {
476 self.range.start = self.range.end; return ::core::option::Option::None;
478 }
479 let value = unsafe { self.subslice.get_value_unchecked(self.range.start + n) };
480 self.range.start += n + 1;
481 ::core::option::Option::Some(value)
482 }
483
484 #[inline]
485 fn size_hint(&self) -> (usize, Option<usize>) {
486 let len = self.range.len();
487 (len, Some(len))
488 }
489 }
490
491 impl<'__iter_ref, #params> ::core::iter::DoubleEndedIterator for #iter<'__iter_ref, #names> #where_clause {
492 #[inline]
493 fn next_back(&mut self) -> Option<Self::Item> {
494 if self.range.is_empty() {
495 return ::core::option::Option::None;
496 }
497 self.range.end -= 1;
498 let value = unsafe { self.subslice.get_value_unchecked(self.range.end) };
499 ::core::option::Option::Some(value)
500 }
501 }
502
503 impl<'__iter_ref, #params> ::core::iter::ExactSizeIterator for #iter<'__iter_ref, #names> #where_clause {
504 #[inline]
505 fn len(&self) -> usize {
506 self.range.len()
507 }
508 }
509
510 #[automatically_derived]
511 impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
512 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
513 type Iter = #iter<'__iter_ref, #names>;
514 }
515
516 #[automatically_derived]
517 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
518 #[inline]
519 fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
520 #iter::new(self.slice)
521 }
522 }
523
524 #[automatically_derived]
525 impl<'__subslice_impl, '__iter_ref,#params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
526 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
527 type IterFrom = #iter<'__iter_ref, #names>;
528 }
529
530 #[automatically_derived]
531 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl<'__subslice_impl, #names> #where_clause {
532 #[inline]
533 fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
534 let len = self.len();
535 assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
536 let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
537 #iter::new_with_range(self.slice, range)
538 }
539 }
540 }.into()
541}
542
543#[proc_macro_derive(IteratorsMut, attributes(value_traits_iterators_mut))]
566pub fn iterators_mut(input: TokenStream) -> TokenStream {
567 let mut input = parse_macro_input!(input as DeriveInput);
568
569 let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators_mut");
571 add_bounds_to_where_clause(&mut input.generics, additional_bounds);
572
573 let input_ident = input.ident;
574 input.generics.make_where_clause();
575 let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
576 let params = get_params_without_defaults(&input.generics);
577 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
578
579 let names = get_names(ty_generics_token_stream);
580 let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
581 let iter = quote::format_ident!("{}Iter", input_ident);
582 quote!{
583 #[automatically_derived]
584 impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
585 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
586 type Iter = #iter<'__iter_ref, #names>;
587 }
588
589 #[automatically_derived]
590 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
591 fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
592 #iter::new(self.slice)
593 }
594 }
595
596 #[automatically_derived]
597 impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
598 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
599 type IterFrom = #iter<'__iter_ref, #names>;
600 }
601
602 #[automatically_derived]
603 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
604 fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
605 let len = self.len();
606 assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
607 let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
608 #iter::new_with_range(self.slice, range)
609 }
610 }
611 }.into()
612}