moverox_codegen/move_struct/
braced.rs1use std::collections::HashMap;
2
3use proc_macro2::{Ident, TokenStream};
4use quote::quote;
5
6use crate::named_fields;
7
8pub(super) trait BracedStructExt {
9 fn to_rust_contents<'a>(
11 &'a self,
12 phantoms: impl Iterator<Item = &'a Ident>,
13 address_map: &HashMap<Ident, TokenStream>,
14 ) -> TokenStream;
15
16 fn impl_new<'a>(
18 &'a self,
19 phantoms: impl Iterator<Item = &'a Ident>,
20 address_map: &HashMap<Ident, TokenStream>,
21 ) -> (TokenStream, TokenStream);
22}
23
24impl BracedStructExt for move_syn::BracedStruct {
25 fn to_rust_contents<'a>(
26 &'a self,
27 phantoms: impl Iterator<Item = &'a Ident>,
28 address_map: &HashMap<Ident, TokenStream>,
29 ) -> TokenStream {
30 named_fields::to_rust(
31 &self.fields,
32 phantoms,
33 address_map,
34 true, )
36 }
37
38 fn impl_new<'a>(
39 &'a self,
40 phantoms: impl Iterator<Item = &'a Ident>,
41 address_map: &HashMap<Ident, TokenStream>,
42 ) -> (TokenStream, TokenStream) {
43 let mut move_fields = named_fields::to_rust_fields(&self.fields, address_map).peekable();
44 let has_fields = move_fields.peek().is_some();
45
46 let args: &mut dyn Iterator<Item = TokenStream> = if has_fields {
47 &mut move_fields
48 .clone()
49 .map(|named_fields::Rust { ident, ty, .. }| quote!(#ident: #ty))
50 } else {
51 &mut std::iter::empty()
52 };
53
54 let assign_args: &mut dyn Iterator<Item = TokenStream> = if !has_fields {
55 &mut std::iter::once(quote!(dummy_field: false))
56 } else {
57 &mut move_fields
58 .clone()
59 .map(|named_fields::Rust { ident, .. }| quote!(#ident))
60 };
61
62 let phantom_data = phantoms.map(|ty| {
63 let field = Ident::new(&format!("_{ty}"), ty.span());
64 quote! {
65 #field: ::std::marker::PhantomData
66 }
67 });
68
69 let args = quote!(#(#args),*);
70 let assignments = quote! {
71 {
72 #(#assign_args,)*
73 #( #phantom_data ),*
74 }
75 };
76 (args, assignments)
77 }
78}