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))]
108pub fn subslices(input: TokenStream) -> TokenStream {
109 let mut input = parse_macro_input!(input as DeriveInput);
110
111 let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices");
113 add_bounds_to_where_clause(&mut input.generics, additional_bounds);
114
115 let input_ident = input.ident;
116 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
117 let params = get_params_without_defaults(&input.generics);
118 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
119
120 let names = get_names(ty_generics_token_stream);
121 let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
122 let mut res = quote! {
123 #[automatically_derived]
124 pub struct #subslice_impl<'__subslice_impl, #params> {
125 slice: &'__subslice_impl #input_ident #ty_generics,
126 range: ::core::ops::Range<usize>,
127 }
128
129 #[automatically_derived]
130 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
131 type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
132
133 #[inline]
134 fn len(&self) -> usize {
135 self.range.len()
136 }
137
138 unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
139 self.slice.get_value_unchecked(index + self.range.start)
140 }
141 }
142
143 #[automatically_derived]
144 impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl<'__subslice_impl, #names> #where_clause {
145 type Subslice = #subslice_impl<'__subslice_gat, #names>;
146 }
147
148 #[automatically_derived]
149 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_impl> for #input_ident #ty_generics #where_clause {
150 type Subslice = #subslice_impl<'__subslice_impl, #names>;
151 }
152 };
153
154 for range_type in [
155 quote! { core::ops::Range<usize> },
156 quote! { core::ops::RangeFrom<usize> },
157 quote! { core::ops::RangeToInclusive<usize> },
158 quote! { core::ops::RangeFull },
159 quote! { core::ops::RangeInclusive<usize> },
160 quote! { core::ops::RangeTo<usize> },
161 ] {
162 res.extend(quote! {
163 #[automatically_derived]
164 impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<#range_type> for #input_ident #ty_generics #where_clause {
165 unsafe fn get_subslice_unchecked(
166 &self,
167 range: #range_type,
168 ) -> ::value_traits::slices::Subslice<'_, Self> {
169 #subslice_impl {
170 slice: &self,
171 range: ::value_traits::slices::ComposeRange::compose(&range, 0..self.len()),
172 }
173 }
174 }
175 #[automatically_derived]
176 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
177 for #subslice_impl<'__subslice_impl, #names> #where_clause
178 {
179 unsafe fn get_subslice_unchecked(
180 &self,
181 range: #range_type,
182 ) -> ::value_traits::slices::Subslice<'_, Self> {
183 #subslice_impl {
184 slice: self.slice,
185 range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
186 }
187 }
188 }
189 });
190 }
191
192 res.into()
193}
194
195#[proc_macro_derive(SubslicesMut, attributes(value_traits_subslices_mut))]
228pub fn subslices_mut(input: TokenStream) -> TokenStream {
229 let mut input = parse_macro_input!(input as DeriveInput);
230
231 let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices_mut");
233 add_bounds_to_where_clause(&mut input.generics, additional_bounds);
234
235 let input_ident = input.ident;
236 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
237 let params = get_params_without_defaults(&input.generics);
238 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
239
240 let names = get_names(ty_generics_token_stream);
241 let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
242 let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
243 let mut res = quote! {
244 #[automatically_derived]
245 pub struct #subslice_impl_mut<'__subslice_impl, #params> {
246 slice: &'__subslice_impl mut #input_ident #ty_generics,
247 range: ::core::ops::Range<usize>,
248 }
249
250 #[automatically_derived]
251 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
252 type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
253
254 #[inline]
255 fn len(&self) -> usize {
256 self.range.len()
257 }
258
259 unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
260 self.slice.get_value_unchecked(index + self.range.start)
261 }
262 }
263
264
265 #[automatically_derived]
266 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueMut for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
267 unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
268 self.slice.set_value_unchecked(index + self.range.start, value)
269 }
270
271 unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
272 self.slice.replace_value_unchecked(index + self.range.start, value)
273 }
274
275 type ChunksMut<'a> = ::core::iter::Empty<&'a mut Self>
276 where
277 Self: 'a;
278
279 type ChunksMutError = ::value_traits::slices::ChunksMutNotSupported;
280
281 fn try_chunks_mut(&mut self, _chunk_size: usize) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
282 Err(::value_traits::slices::ChunksMutNotSupported)
284 }
285 }
286
287 #[automatically_derived]
288 impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
289 type Subslice = #subslice_impl<'__subslice_gat, #names>;
290 }
291
292 #[automatically_derived]
293 impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
294 type SubsliceMut = #subslice_impl_mut<'__subslice_gat, #names>;
295 }
296
297 #[automatically_derived]
298 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_impl> for #input_ident #ty_generics #where_clause {
299 type SubsliceMut = #subslice_impl_mut<'__subslice_impl, #names>;
300 }
301
302 };
303
304 for range_type in [
305 quote! { ::core::ops::Range<usize> },
306 quote! { ::core::ops::RangeFrom<usize> },
307 quote! { ::core::ops::RangeToInclusive<usize> },
308 quote! { ::core::ops::RangeFull },
309 quote! { ::core::ops::RangeInclusive<usize> },
310 quote! { ::core::ops::RangeTo<usize> },
311 ] {
312 res.extend(quote!{
314 #[automatically_derived]
315 impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type> for #input_ident #ty_generics #where_clause {
316 unsafe fn get_subslice_unchecked_mut(
317 &mut self,
318 range: #range_type,
319 ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
320 let len = self.len();
321 #subslice_impl_mut {
322 slice: self,
323 range: ::value_traits::slices::ComposeRange::compose(&range, 0..len),
324 }
325 }
326 }
327 #[automatically_derived]
328 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
329 for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
330 {
331 unsafe fn get_subslice_unchecked(
332 &self,
333 range: #range_type,
334 ) -> ::value_traits::slices::Subslice<'_, Self> {
335 #subslice_impl {
336 slice: &*self.slice,
337 range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
338 }
339 }
340 }
341 #[automatically_derived]
342 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type>
343 for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
344 {
345 unsafe fn get_subslice_unchecked_mut(
346 &mut self,
347 range: #range_type,
348 ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
349 #subslice_impl_mut {
350 slice: self.slice,
351 range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
352 }
353 }
354 }
355 });
356 }
357
358 res.into()
359}
360
361#[proc_macro_derive(Iterators, attributes(value_traits_iterators))]
385pub fn iterators(input: TokenStream) -> TokenStream {
386 let mut input = parse_macro_input!(input as DeriveInput);
387
388 let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators");
390 add_bounds_to_where_clause(&mut input.generics, additional_bounds);
391
392 let input_ident = input.ident;
393 input.generics.make_where_clause();
394 let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
395 let params = get_params_without_defaults(&input.generics);
396 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
397
398 let names = get_names(ty_generics_token_stream);
399 let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
400 let iter = quote::format_ident!("{}Iter", input_ident);
401 quote! {
402 #[automatically_derived]
403 pub struct #iter<'__iter_ref, #params> {
404 subslice: &'__iter_ref #input_ident #ty_generics,
405 range: ::core::ops::Range<usize>,
406 }
407
408 #[automatically_derived]
409 impl<'__iter_ref, #params> #iter<'__iter_ref, #names> #where_clause {
410 pub fn new(subslice: &'__iter_ref #input_ident #ty_generics) -> Self {
411 let len = subslice.len();
412 Self {
413 subslice,
414 range: 0..len,
415 }
416 }
417 pub fn new_with_range(subslice: &'__iter_ref #input_ident #ty_generics, range: ::core::ops::Range<usize>) -> Self {
418 Self {
419 subslice,
420 range,
421 }
422 }
423 }
424
425 #[automatically_derived]
455 impl<'__iter_ref, #params> ::core::iter::Iterator for #iter<'__iter_ref, #names> #where_clause {
460 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
461
462 #[inline]
463 fn next(&mut self) -> Option<Self::Item> {
464 if self.range.is_empty() {
465 return ::core::option::Option::None;
466 }
467 let value = unsafe { self.subslice.get_value_unchecked(self.range.start) };
468 self.range.start += 1;
469 ::core::option::Option::Some(value)
470 }
471
472 #[inline]
475 fn nth(&mut self, n: usize) -> Option<Self::Item> {
476 if n >= self.range.end {
477 self.range.start = self.range.end; return ::core::option::Option::None;
479 }
480 let value = unsafe { self.subslice.get_value_unchecked(self.range.start + n) };
481 self.range.start += n + 1;
482 ::core::option::Option::Some(value)
483 }
484
485 #[inline]
486 fn size_hint(&self) -> (usize, Option<usize>) {
487 let len = self.range.len();
488 (len, Some(len))
489 }
490 }
491
492 impl<'__iter_ref, #params> ::core::iter::DoubleEndedIterator for #iter<'__iter_ref, #names> #where_clause {
493 #[inline]
494 fn next_back(&mut self) -> Option<Self::Item> {
495 if self.range.is_empty() {
496 return ::core::option::Option::None;
497 }
498 self.range.end -= 1;
499 let value = unsafe { self.subslice.get_value_unchecked(self.range.end) };
500 ::core::option::Option::Some(value)
501 }
502 }
503
504 impl<'__iter_ref, #params> ::core::iter::ExactSizeIterator for #iter<'__iter_ref, #names> #where_clause {
505 #[inline]
506 fn len(&self) -> usize {
507 self.range.len()
508 }
509 }
510
511 #[automatically_derived]
512 impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
513 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
514 type Iter = #iter<'__iter_ref, #names>;
515 }
516
517 #[automatically_derived]
518 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
519 #[inline]
520 fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
521 #iter::new(self.slice)
522 }
523 }
524
525 #[automatically_derived]
526 impl<'__subslice_impl, '__iter_ref,#params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
527 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
528 type IterFrom = #iter<'__iter_ref, #names>;
529 }
530
531 #[automatically_derived]
532 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl<'__subslice_impl, #names> #where_clause {
533 #[inline]
534 fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
535 let len = self.len();
536 assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
537 let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
538 #iter::new_with_range(self.slice, range)
539 }
540 }
541 }.into()
542}
543
544#[proc_macro_derive(IteratorsMut, attributes(value_traits_iterators_mut))]
565pub fn iterators_mut(input: TokenStream) -> TokenStream {
566 let mut input = parse_macro_input!(input as DeriveInput);
567
568 let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators_mut");
570 add_bounds_to_where_clause(&mut input.generics, additional_bounds);
571
572 let input_ident = input.ident;
573 input.generics.make_where_clause();
574 let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
575 let params = get_params_without_defaults(&input.generics);
576 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
577
578 let names = get_names(ty_generics_token_stream);
579 let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
580 let iter = quote::format_ident!("{}Iter", input_ident);
581 quote!{
582 #[automatically_derived]
583 impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
584 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
585 type Iter = #iter<'__iter_ref, #names>;
586 }
587
588 #[automatically_derived]
589 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
590 fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
591 #iter::new(self.slice)
592 }
593 }
594
595 #[automatically_derived]
596 impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
597 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
598 type IterFrom = #iter<'__iter_ref, #names>;
599 }
600
601 #[automatically_derived]
602 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
603 fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
604 let len = self.len();
605 assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
606 let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
607 #iter::new_with_range(self.slice, range)
608 }
609 }
610 }.into()
611}