1use proc_macro::TokenStream;
2use quote::{ToTokens, format_ident, quote};
3use syn::{Attribute, Data, DeriveInput, Fields, Path, PathArguments, Type, parse_macro_input};
4
5#[proc_macro_derive(Soa, attributes(soa))]
128pub fn derive_soa(input: TokenStream) -> TokenStream {
129 use syn::TypePath;
130
131 let input = parse_macro_input!(input as DeriveInput);
132 let visibility = &input.vis;
133 let derive_reflect = input
134 .attrs
135 .iter()
136 .any(|attr| attr.path().is_ident("reflect"));
137 let reflect_import = if derive_reflect {
138 quote!(
139 use super::{bevy_reflect, Reflect};
140 )
141 } else {
142 quote!()
143 };
144 let soa_reflect_attrs = if derive_reflect {
145 quote! {
146 #[derive(Reflect)]
147 #[reflect(from_reflect = false)]
148 }
149 } else {
150 quote!()
151 };
152
153 let name = &input.ident;
154 if let Some(lifetime) = input.generics.lifetimes().next() {
155 return syn::Error::new_spanned(lifetime, "lifetime parameters are not supported")
156 .to_compile_error()
157 .into();
158 }
159 if let Some(const_param) = input.generics.const_params().next() {
160 return syn::Error::new_spanned(const_param, "const parameters are not supported")
161 .to_compile_error()
162 .into();
163 }
164 if let Some(where_clause) = &input.generics.where_clause {
165 return syn::Error::new_spanned(where_clause, "where clauses are not supported")
166 .to_compile_error()
167 .into();
168 }
169 let ty_params: Vec<syn::TypeParam> = input
170 .generics
171 .type_params()
172 .cloned()
173 .map(|mut param| {
174 param.attrs.clear();
175 param.default = None;
176 param
177 })
178 .collect();
179 let ty_idents: Vec<syn::Ident> = ty_params.iter().map(|param| param.ident.clone()).collect();
180 if let Some(clashing) = ty_idents.iter().find(|ident| *ident == "N") {
182 return syn::Error::new_spanned(
183 clashing,
184 "a type parameter named `N` collides with the generated capacity parameter; rename it",
185 )
186 .to_compile_error()
187 .into();
188 }
189 let has_type_params = !ty_params.is_empty();
190
191 let soa_decl = quote!(<#(#ty_params,)* const N: usize>);
194 let soa_use = quote!(<#(#ty_idents,)* N>);
195 let iter_decl = quote!(<'a, #(#ty_params,)* const N: usize>);
196 let iter_use = quote!(<'a, #(#ty_idents,)* N>);
197 let iter_use_elided = quote!(<#(#ty_idents,)* N>);
198 let serde_decl = quote!(<'a, #(#ty_params,)* const N: usize>);
199 let serde_use = quote!(<'a, #(#ty_idents,)* N>);
200 let serde_use_anon = quote!(<'_, #(#ty_idents,)* N>);
201 let de_decl = quote!(<'de, #(#ty_params,)* const N: usize>);
202 let wire_decl = if has_type_params {
203 quote!(<#(#ty_params),*>)
204 } else {
205 quote!()
206 };
207 let wire_use = if has_type_params {
208 quote!(<#(#ty_idents),*>)
209 } else {
210 quote!()
211 };
212 let orig_ty = if has_type_params {
213 quote!(super::#name<#(#ty_idents),*>)
214 } else {
215 quote!(super::#name)
216 };
217 let parent_scope_import = if has_type_params {
220 quote!(
221 #[allow(unused_imports)]
222 use super::*;
223 )
224 } else {
225 quote!()
226 };
227 let module_name = format_ident!("{}_soa", name.to_string().to_lowercase());
228 let soa_struct_name = format_ident!("{}Soa", name);
229 let soa_storage_name = format_ident!("{}SoaStorage", name);
230 let soa_storage_wire_name = format_ident!("{}SoaStorageWire", name);
231 let soa_storage_serde_name = format_ident!("{}SoaStorageSerde", name);
232 let soa_struct_wire_name = format_ident!("{}SoaWire", name);
233
234 let data = match &input.data {
235 Data::Struct(data) => data,
236 _ => {
237 return syn::Error::new_spanned(&input, "Only structs are supported")
238 .to_compile_error()
239 .into();
240 }
241 };
242 let fields = match &data.fields {
243 Fields::Named(fields) => &fields.named,
244 _ => {
245 return syn::Error::new_spanned(&data.fields, "Only named fields are supported")
246 .to_compile_error()
247 .into();
248 }
249 };
250
251 struct FieldInfo {
252 name: syn::Ident,
253 ty: syn::Type,
254 nested: bool,
255 storage_path: Option<syn::Path>,
256 storage_wire_path: Option<syn::Path>,
257 }
258
259 let mut field_infos = Vec::new();
260 let mut unique_imports = vec![];
261 let mut unique_import_names = vec![];
262
263 fn is_primitive(type_name: &str) -> bool {
264 matches!(
265 type_name,
266 "i8" | "i16"
267 | "i32"
268 | "i64"
269 | "i128"
270 | "u8"
271 | "u16"
272 | "u32"
273 | "u64"
274 | "u128"
275 | "f32"
276 | "f64"
277 | "bool"
278 | "char"
279 | "str"
280 | "usize"
281 | "isize"
282 )
283 }
284
285 fn parse_soa_nested(attrs: &[Attribute]) -> Result<bool, syn::Error> {
286 let mut nested = false;
287 for attr in attrs {
288 if attr.path().is_ident("soa") {
289 attr.parse_nested_meta(|meta| {
290 if meta.path.is_ident("nested") {
291 nested = true;
292 Ok(())
293 } else {
294 Err(meta.error("unsupported #[soa] option, expected `nested`"))
295 }
296 })?;
297 }
298 }
299 Ok(nested)
300 }
301
302 fn qualify_path(path: &Path) -> Path {
303 if path.leading_colon.is_some() {
304 return path.clone();
305 }
306 if let Some(first) = path.segments.first() {
307 if first.ident == "crate" {
308 return path.clone();
309 }
310 if first.ident == "self" {
311 let mut path = path.clone();
312 if let Some(segment) = path.segments.first_mut() {
313 segment.ident = format_ident!("super");
314 }
315 return path;
316 }
317 if first.ident == "std" || first.ident == "core" || first.ident == "alloc" {
318 return path.clone();
319 }
320 }
321 syn::parse_quote!(super::#path)
322 }
323
324 fn storage_paths(field_type: &Type) -> Result<(Path, Path), syn::Error> {
325 let Type::Path(type_path) = field_type else {
326 return Err(syn::Error::new_spanned(
327 field_type,
328 "expected a path type for #[soa(nested)]",
329 ));
330 };
331
332 let mut storage_path = type_path.path.clone();
333 let last_segment = storage_path
334 .segments
335 .last_mut()
336 .ok_or_else(|| syn::Error::new_spanned(field_type, "expected a non-empty type path"))?;
337 if !matches!(last_segment.arguments, PathArguments::None) {
338 return Err(syn::Error::new_spanned(
339 field_type,
340 "generic types are not supported with #[soa(nested)]",
341 ));
342 }
343 let base_ident = last_segment.ident.clone();
344 last_segment.ident = format_ident!("{}SoaStorage", base_ident);
345
346 let mut storage_wire_path = type_path.path.clone();
347 let last_wire_segment = storage_wire_path
348 .segments
349 .last_mut()
350 .ok_or_else(|| syn::Error::new_spanned(field_type, "expected a non-empty type path"))?;
351 last_wire_segment.ident = format_ident!("{}SoaStorageWire", base_ident);
352
353 Ok((
354 qualify_path(&storage_path),
355 qualify_path(&storage_wire_path),
356 ))
357 }
358
359 for field in fields {
360 let field_name = match &field.ident {
361 Some(ident) => ident.clone(),
362 None => {
363 return syn::Error::new_spanned(field, "Only named fields are supported")
364 .to_compile_error()
365 .into();
366 }
367 };
368 let field_type = field.ty.clone();
369 let nested = match parse_soa_nested(&field.attrs) {
370 Ok(value) => value,
371 Err(err) => return err.to_compile_error().into(),
372 };
373 if nested && has_type_params {
374 return syn::Error::new_spanned(
375 field,
376 "#[soa(nested)] is not supported on generic structs",
377 )
378 .to_compile_error()
379 .into();
380 }
381 let (storage_path, storage_wire_path) = if nested {
382 match storage_paths(&field_type) {
383 Ok((storage_path, storage_wire_path)) => {
384 (Some(storage_path), Some(storage_wire_path))
385 }
386 Err(err) => return err.to_compile_error().into(),
387 }
388 } else {
389 (None, None)
390 };
391
392 if let Type::Path(TypePath { path, .. }) = &field_type {
393 let Some(last_segment) = path.segments.last() else {
394 return syn::Error::new_spanned(path, "expected a non-empty type path")
395 .to_compile_error()
396 .into();
397 };
398 let type_name = last_segment.ident.to_string();
399 let path_str = path.to_token_stream().to_string();
400 let is_type_param = path.segments.len() == 1
401 && path.leading_colon.is_none()
402 && ty_idents.contains(&last_segment.ident);
403
404 if !is_primitive(&type_name)
405 && !is_type_param
406 && !unique_import_names.contains(&path_str)
407 {
408 unique_imports.push(path.clone());
409 unique_import_names.push(path_str);
410 }
411 }
412
413 field_infos.push(FieldInfo {
414 name: field_name,
415 ty: field_type,
416 nested,
417 storage_path,
418 storage_wire_path,
419 });
420 }
421
422 let field_names: Vec<_> = field_infos.iter().map(|info| &info.name).collect();
423 let field_types: Vec<_> = field_infos.iter().map(|info| &info.ty).collect();
424
425 let soa_struct_name_iterator = format_ident!("{}Iterator", name);
426 let storage_field_count = field_names.len();
427 let field_count = storage_field_count + 1; let mut field_decls = Vec::new();
431 let mut new_inits = Vec::new();
432 let mut default_inits = Vec::new();
433 let mut get_fields = Vec::new();
434 let mut set_fields = Vec::new();
435 let mut accessors = Vec::new();
436
437 let mut soa_push_fields = Vec::new();
439 let mut soa_pop_fields = Vec::new();
440 let mut soa_apply_args = Vec::new();
441 let mut soa_apply_sets = Vec::new();
442 let mut soa_encode_fields = Vec::new();
443 let mut soa_decode_fields = Vec::new();
444 let mut soa_serialize_fields = Vec::new();
445 let mut soa_serialize_bounds = Vec::new();
446 let mut soa_deserialize_bounds = Vec::new();
447 let mut soa_wire_fields = Vec::new();
448 let mut soa_wire_checks = Vec::new();
449 let mut soa_wire_assignments = Vec::new();
450
451 let mut generic_method_bounds = Vec::new();
454 let mut generic_encode_bounds = Vec::new();
455 let mut generic_decode_bounds = Vec::new();
456 let mut generic_default_bounds = Vec::new();
457
458 let mut storage_encode_fields = Vec::new();
460 let mut storage_decode_fields = Vec::new();
461 let mut storage_serialize_fields = Vec::new();
462 let mut storage_serialize_bounds = Vec::new();
463 let mut storage_clone_bounds = Vec::new();
464 let mut storage_wire_fields = Vec::new();
465 let mut storage_wire_checks = Vec::new();
466 let mut storage_wire_assignments = Vec::new();
467
468 for info in &field_infos {
469 let name = &info.name;
470 let ty = &info.ty;
471 let name_mut = format_ident!("{}_mut", name);
472
473 if info.nested {
474 let storage_path = info
475 .storage_path
476 .as_ref()
477 .expect("nested field missing storage path");
478 let storage_wire_path = info
479 .storage_wire_path
480 .as_ref()
481 .expect("nested field missing storage wire path");
482 let serde_name = format_ident!("{}_serde", name);
483
484 field_decls.push(quote!(pub #name: #storage_path<N>));
485 new_inits.push(quote!(#name: #storage_path::<N>::new(default.#name.clone())));
486 default_inits.push(quote!(#name: #storage_path::<N>::default()));
487 storage_clone_bounds.push(quote!(#storage_path<N>: Clone,));
488
489 accessors.push(quote! {
490 pub fn #name(&self) -> &#storage_path<N> {
491 &self.#name
492 }
493
494 pub fn #name_mut(&mut self) -> &mut #storage_path<N> {
495 &mut self.#name
496 }
497 });
498
499 get_fields.push(quote!(#name: self.#name.get(index),));
500 set_fields.push(quote!(self.#name.set(index, value.#name.clone());));
501
502 soa_push_fields.push(quote!(self.#name.set(self.len, value.#name.clone());));
503 soa_pop_fields.push(quote!(#name: self.#name.get(self.len),));
504
505 soa_apply_args.push(quote!(self.#name.get(_idx)));
506 soa_apply_sets.push(quote!(self.#name.set(_idx, #name);));
507
508 storage_encode_fields.push(quote!(self.#name.encode_len(encoder, len)?;));
509 storage_decode_fields
510 .push(quote!(result.#name = #storage_path::<N>::decode_len(decoder, len)?;));
511
512 soa_encode_fields.push(quote!(self.#name.encode_len(encoder, self.len)?;));
513 soa_decode_fields
514 .push(quote!(result.#name = #storage_path::<N>::decode_len(decoder, result.len)?;));
515
516 storage_serialize_fields.push(quote! {
517 {
518 let #serde_name = self.storage.#name.serialize_len(self.len);
519 state.serialize_field(stringify!(#name), &#serde_name)?;
520 }
521 });
522 soa_serialize_fields.push(quote! {
523 {
524 let #serde_name = self.#name.serialize_len(self.len);
525 state.serialize_field(stringify!(#name), &#serde_name)?;
526 }
527 });
528
529 storage_wire_fields.push(quote!(#name: #storage_wire_path,));
530 storage_wire_assignments.push(quote!(
531 result.#name = #storage_path::<N>::from_wire(#name, len)
532 .map_err(|err| format!("field {}: {}", stringify!(#name), err))?;
533 ));
534
535 soa_wire_fields.push(quote!(#name: #storage_wire_path,));
536 soa_wire_assignments.push(quote!(
537 result.#name = #storage_path::<N>::from_wire(#name, len)
538 .map_err(|err| serde::de::Error::custom(format!(
539 "field {}: {}",
540 stringify!(#name),
541 err
542 )))?;
543 ));
544 } else {
545 let name_range = format_ident!("{}_range", name);
546 let name_range_mut = format_ident!("{}_range_mut", name);
547
548 field_decls.push(quote!(pub #name: [#ty; N]));
549 new_inits.push(quote!(#name: from_fn(|_| default.#name.clone())));
550 default_inits.push(quote!(#name: from_fn(|_| #ty::default())));
551 storage_clone_bounds.push(quote!(#ty: Clone,));
552 if has_type_params {
553 generic_method_bounds.push(quote!(#ty: Clone + Default,));
554 generic_encode_bounds.push(quote!(#ty: Encode,));
555 generic_decode_bounds.push(quote!(#ty: Decode<()> + Default,));
556 generic_default_bounds.push(quote!(#ty: Default,));
557 }
558
559 accessors.push(quote! {
560 pub fn #name(&self) -> &[#ty] {
561 &self.#name
562 }
563
564 pub fn #name_mut(&mut self) -> &mut [#ty] {
565 &mut self.#name
566 }
567
568 pub fn #name_range(&self, range: core::ops::Range<usize>) -> &[#ty] {
569 &self.#name[range]
570 }
571
572 pub fn #name_range_mut(&mut self, range: core::ops::Range<usize>) -> &mut [#ty] {
573 &mut self.#name[range]
574 }
575 });
576
577 get_fields.push(quote!(#name: self.#name[index].clone(),));
578 set_fields.push(quote!(self.#name[index] = value.#name.clone();));
579
580 soa_push_fields.push(quote!(self.#name[self.len] = value.#name.clone();));
581 soa_pop_fields.push(quote!(#name: self.#name[self.len].clone(),));
582
583 soa_apply_args.push(quote!(self.#name[_idx].clone()));
584 soa_apply_sets.push(quote!(self.#name[_idx] = #name;));
585
586 storage_encode_fields.push(quote! {
587 for _idx in 0..len {
588 Encode::encode(&self.#name[_idx], encoder)?;
589 }
590 });
591 storage_decode_fields.push(quote! {
592 for _idx in 0..len {
593 result.#name[_idx] = Decode::decode(decoder)?;
594 }
595 });
596
597 soa_encode_fields.push(quote! {
598 for _idx in 0..self.len {
599 Encode::encode(&self.#name[_idx], encoder)?;
600 }
601 });
602 soa_decode_fields.push(quote! {
603 for _idx in 0..result.len {
604 result.#name[_idx] = Decode::decode(decoder)?;
605 }
606 });
607
608 storage_serialize_fields.push(quote! {
609 state.serialize_field(stringify!(#name), &self.storage.#name[..self.len])?;
610 });
611 soa_serialize_fields.push(quote! {
612 state.serialize_field(stringify!(#name), &self.#name[..self.len])?;
613 });
614
615 storage_serialize_bounds.push(quote!(#ty: Serialize,));
616 soa_serialize_bounds.push(quote!(#ty: Serialize,));
617 soa_deserialize_bounds.push(quote!(#ty: Deserialize<'de> + Default,));
618
619 storage_wire_fields.push(quote!(#name: Vec<#ty>,));
620 storage_wire_checks.push(quote! {
621 if #name.len() != len {
622 return Err(format!(
623 "field {} has length {} but len is {}",
624 stringify!(#name),
625 #name.len(),
626 len
627 ));
628 }
629 });
630 storage_wire_assignments.push(quote! {
631 for (idx, value) in #name.into_iter().enumerate() {
632 result.#name[idx] = value;
633 }
634 });
635
636 soa_wire_fields.push(quote!(#name: Vec<#ty>,));
637 soa_wire_checks.push(quote! {
638 if #name.len() != len {
639 return Err(serde::de::Error::custom(format!(
640 "field {} has length {} but len is {}",
641 stringify!(#name),
642 #name.len(),
643 len
644 )));
645 }
646 });
647 soa_wire_assignments.push(quote! {
648 for (idx, value) in #name.into_iter().enumerate() {
649 result.#name[idx] = value;
650 }
651 });
652 }
653 }
654
655 let storage_clone_where = if storage_clone_bounds.is_empty() {
656 quote!()
657 } else {
658 quote!(where #(#storage_clone_bounds)*)
659 };
660 let storage_serialize_where = if storage_serialize_bounds.is_empty() {
661 quote!()
662 } else {
663 quote!(where #(#storage_serialize_bounds)*)
664 };
665 let soa_serialize_where = if soa_serialize_bounds.is_empty() {
666 quote!()
667 } else {
668 quote!(where #(#soa_serialize_bounds)*)
669 };
670 let soa_deserialize_where = if soa_deserialize_bounds.is_empty() {
671 quote!()
672 } else {
673 quote!(where #(#soa_deserialize_bounds)*)
674 };
675 let methods_where = if generic_method_bounds.is_empty() {
676 quote!()
677 } else {
678 quote!(where #(#generic_method_bounds)*)
679 };
680 let storage_methods_where = if generic_method_bounds.is_empty() {
681 quote!()
682 } else {
683 quote!(where #(#generic_method_bounds)* #(#generic_encode_bounds)* #(#generic_decode_bounds)*)
684 };
685 let encode_where = if generic_encode_bounds.is_empty() {
686 quote!()
687 } else {
688 quote!(where #(#generic_encode_bounds)*)
689 };
690 let decode_where = if generic_decode_bounds.is_empty() {
691 quote!()
692 } else {
693 quote!(where #(#generic_decode_bounds)*)
694 };
695 let default_where = if generic_default_bounds.is_empty() {
696 quote!()
697 } else {
698 quote!(where #(#generic_default_bounds)*)
699 };
700
701 let iterator = quote! {
702 pub struct #soa_struct_name_iterator #iter_decl {
703 soa_struct: &'a #soa_struct_name #soa_use,
704 current: usize,
705 }
706
707 impl #iter_decl #soa_struct_name_iterator #iter_use
708 #methods_where
709 {
710 pub fn new(soa_struct: &'a #soa_struct_name #soa_use) -> Self {
711 Self {
712 soa_struct,
713 current: 0,
714 }
715 }
716 }
717
718 impl #iter_decl Iterator for #soa_struct_name_iterator #iter_use
719 #methods_where
720 {
721 type Item = #orig_ty;
722
723 fn next(&mut self) -> Option<Self::Item> {
724 if self.current < self.soa_struct.len {
725 let item = self.soa_struct.get(self.current); self.current += 1;
727 Some(item)
728 } else {
729 None
730 }
731 }
732 }
733 };
734
735 let expanded = quote! {
736 #visibility mod #module_name {
737 extern crate alloc;
738 use self::alloc::format;
739 use self::alloc::string::String;
740 use self::alloc::vec::Vec;
741 use bincode::{Decode, Encode};
742 use bincode::enc::Encoder;
743 use bincode::de::Decoder;
744 use bincode::error::{DecodeError, EncodeError};
745 use serde::Deserialize;
746 use serde::Serialize;
747 use serde::Serializer;
748 use serde::ser::SerializeStruct;
749 #parent_scope_import
750 #( use super::#unique_imports; )*
751 #reflect_import
752 use core::array::from_fn;
753
754 #[derive(Debug)]
755 #visibility struct #soa_storage_name #soa_decl {
756 #(#field_decls,)*
757 }
758
759 #[doc(hidden)]
760 #[derive(Deserialize)]
761 #visibility struct #soa_storage_wire_name #wire_decl {
762 #(#storage_wire_fields)*
763 }
764
765 #[doc(hidden)]
766 #visibility struct #soa_storage_serde_name #serde_decl {
767 storage: &'a #soa_storage_name #soa_use,
768 len: usize,
769 }
770
771 impl #soa_decl #soa_storage_name #soa_use
772 #storage_methods_where
773 {
774 pub fn new(default: #orig_ty) -> Self {
775 Self {
776 #(#new_inits,)*
777 }
778 }
779
780 pub fn set(&mut self, index: usize, value: #orig_ty) {
781 assert!(index < N, "Index out of bounds");
782 #(#set_fields)*
783 }
784
785 pub fn get(&self, index: usize) -> #orig_ty {
786 assert!(index < N, "Index out of bounds");
787 super::#name {
788 #(#get_fields)*
789 }
790 }
791
792 pub fn encode_len<E: Encoder>(
793 &self,
794 encoder: &mut E,
795 len: usize,
796 ) -> Result<(), EncodeError> {
797 #(#storage_encode_fields)*
798 Ok(())
799 }
800
801 pub fn decode_len<D: Decoder<Context = ()>>(
802 decoder: &mut D,
803 len: usize,
804 ) -> Result<Self, DecodeError> {
805 if len > N {
806 return Err(DecodeError::ArrayLengthMismatch {
807 required: N,
808 found: len,
809 });
810 }
811 let mut result = Self::default();
812 #(#storage_decode_fields)*
813 Ok(result)
814 }
815
816 pub fn serialize_len(&self, len: usize) -> #soa_storage_serde_name #serde_use_anon {
817 #soa_storage_serde_name {
818 storage: self,
819 len,
820 }
821 }
822
823 pub fn from_wire(wire: #soa_storage_wire_name #wire_use, len: usize) -> Result<Self, String> {
824 let #soa_storage_wire_name { #( #field_names ),* } = wire;
825
826 if len > N {
827 return Err(format!(
828 "len {} exceeds capacity {}",
829 len,
830 N
831 ));
832 }
833
834 #(#storage_wire_checks)*
835
836 let mut result = Self::default();
837 #(#storage_wire_assignments)*
838 Ok(result)
839 }
840
841 #(#accessors)*
842 }
843
844 impl #serde_decl Serialize for #soa_storage_serde_name #serde_use
845 #storage_serialize_where
846 {
847 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
848 where
849 S: Serializer,
850 {
851 let mut state = serializer.serialize_struct(
852 stringify!(#soa_storage_name),
853 #storage_field_count,
854 )?;
855 #(#storage_serialize_fields)*
856 state.end()
857 }
858 }
859
860 impl #soa_decl Default for #soa_storage_name #soa_use
861 #default_where
862 {
863 fn default() -> Self {
864 Self {
865 #(#default_inits,)*
866 }
867 }
868 }
869
870 impl #soa_decl Clone for #soa_storage_name #soa_use
871 #storage_clone_where
872 {
873 fn clone(&self) -> Self {
874 Self {
875 #( #field_names: self.#field_names.clone(), )*
876 }
877 }
878 }
879
880 #[derive(Debug)]
881 #soa_reflect_attrs
882 #visibility struct #soa_struct_name #soa_decl {
883 pub len: usize,
884 #(#field_decls,)*
885 }
886
887 impl #soa_decl #soa_struct_name #soa_use {
890 pub fn len(&self) -> usize {
891 self.len
892 }
893
894 pub fn is_empty(&self) -> bool {
895 self.len == 0
896 }
897 }
898
899 impl #soa_decl #soa_struct_name #soa_use
900 #methods_where
901 {
902 pub fn new(default: #orig_ty) -> Self {
903 Self {
904 #(#new_inits,)*
905 len: 0,
906 }
907 }
908
909 pub fn push(&mut self, value: #orig_ty) {
910 if self.len < N {
911 #(#soa_push_fields)*
912 self.len += 1;
913 } else {
914 panic!("Capacity exceeded")
915 }
916 }
917
918 pub fn pop(&mut self) -> Option<#orig_ty> {
919 if self.len == 0 {
920 None
921 } else {
922 self.len -= 1;
923 Some(super::#name {
924 #(#soa_pop_fields)*
925 })
926 }
927 }
928
929 pub fn set(&mut self, index: usize, value: #orig_ty) {
930 assert!(index < self.len, "Index out of bounds");
931 #(#set_fields)*
932 }
933
934 pub fn get(&self, index: usize) -> #orig_ty {
935 assert!(index < self.len, "Index out of bounds");
936 super::#name {
937 #(#get_fields)*
938 }
939 }
940
941 pub fn apply<F>(&mut self, mut f: F)
942 where
943 F: FnMut(#(#field_types),*) -> (#(#field_types),*)
944 {
945 for _idx in 0..self.len {
947 let result = f(#(#soa_apply_args),*);
948 let (#(#field_names),*) = result;
949 #(#soa_apply_sets)*
950 }
951 }
952
953 pub fn iter(&self) -> #soa_struct_name_iterator #iter_use_elided {
954 #soa_struct_name_iterator::new(self)
955 }
956
957 #(#accessors)*
958 }
959
960 impl #soa_decl Encode for #soa_struct_name #soa_use
961 #encode_where
962 {
963 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
964 Encode::encode(&self.len, encoder)?;
965 #(#soa_encode_fields)*
966 Ok(())
967 }
968 }
969
970 impl #soa_decl Decode<()> for #soa_struct_name #soa_use
971 #decode_where
972 {
973 fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, DecodeError> {
974 let mut result = Self::default();
975 result.len = Decode::decode(decoder)?;
976 if result.len > N {
978 return Err(DecodeError::ArrayLengthMismatch {
979 required: N,
980 found: result.len,
981 });
982 }
983 #(#soa_decode_fields)*
984 Ok(result)
985 }
986 }
987
988 impl #soa_decl Default for #soa_struct_name #soa_use
989 #default_where
990 {
991 fn default() -> Self {
992 Self {
993 #(#default_inits,)*
994 len: 0,
995 }
996 }
997 }
998
999 impl #soa_decl Clone for #soa_struct_name #soa_use
1000 #storage_clone_where
1001 {
1002 fn clone(&self) -> Self {
1003 Self {
1004 #( #field_names: self.#field_names.clone(), )*
1005 len: self.len,
1006 }
1007 }
1008 }
1009
1010 impl #soa_decl Serialize for #soa_struct_name #soa_use
1011 #soa_serialize_where
1012 {
1013 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1014 where
1015 S: Serializer,
1016 {
1017 let mut state =
1018 serializer.serialize_struct(stringify!(#soa_struct_name), #field_count)?;
1019 state.serialize_field("len", &self.len)?;
1020 #(#soa_serialize_fields)*
1021 state.end()
1022 }
1023 }
1024
1025 impl #de_decl Deserialize<'de> for #soa_struct_name #soa_use
1026 #soa_deserialize_where
1027 {
1028 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1029 where
1030 D: serde::Deserializer<'de>,
1031 {
1032 #[derive(Deserialize)]
1033 struct #soa_struct_wire_name #wire_decl {
1034 len: usize,
1035 #(#soa_wire_fields)*
1036 }
1037
1038 let wire = #soa_struct_wire_name::deserialize(deserializer)?;
1039 let #soa_struct_wire_name { len, #( #field_names ),* } = wire;
1040
1041 if len > N {
1042 return Err(serde::de::Error::custom(format!(
1043 "len {} exceeds capacity {}",
1044 len,
1045 N
1046 )));
1047 }
1048
1049 #(#soa_wire_checks)*
1050
1051 let mut result = Self::default();
1052 result.len = len;
1053 #(#soa_wire_assignments)*
1054 Ok(result)
1055 }
1056 }
1057
1058 #iterator
1059 }
1060 #visibility use #module_name::#soa_struct_name;
1061 #visibility use #module_name::#soa_storage_name;
1062 #visibility use #module_name::#soa_storage_wire_name;
1063 #visibility use #module_name::#soa_struct_name_iterator;
1064 };
1065
1066 let tokens: TokenStream = expanded.into();
1067
1068 tokens
1069}