moverox_codegen/move_struct/
tuple.rs1use std::collections::HashMap;
2
3use proc_macro2::{Ident, Span, TokenStream};
4use quote::quote;
5use unsynn::ToTokens as _;
6
7use crate::move_type;
8
9pub(super) trait TupleStructExt {
10 fn to_rust_contents<'a>(
12 &'a self,
13 phantoms: impl Iterator<Item = &'a Ident>,
14 address_map: &HashMap<Ident, TokenStream>,
15 ) -> TokenStream;
16
17 fn impl_new<'a>(
19 &'a self,
20 phantoms: impl Iterator<Item = &'a Ident>,
21 address_map: &HashMap<Ident, TokenStream>,
22 ) -> (TokenStream, TokenStream);
23}
24
25impl TupleStructExt for move_syn::TupleStruct {
26 fn to_rust_contents<'a>(
27 &'a self,
28 phantoms: impl Iterator<Item = &'a Ident>,
29 address_map: &HashMap<Ident, TokenStream>,
30 ) -> TokenStream {
31 let parenthesized_fields = crate::positional_fields::to_rust(
32 &self.fields,
33 phantoms,
34 address_map,
35 true, true, );
38
39 quote! {
40 #parenthesized_fields;
41 }
42 }
43
44 fn impl_new<'a>(
45 &'a self,
46 phantoms: impl Iterator<Item = &'a Ident>,
47 address_map: &HashMap<Ident, TokenStream>,
48 ) -> (TokenStream, TokenStream) {
49 let move_fields = self.fields();
50
51 let args: &mut dyn Iterator<Item = TokenStream> = if self.is_empty() {
52 &mut std::iter::empty()
53 } else {
54 &mut move_fields.clone().enumerate().map(|(i, d)| {
55 let ty = move_type::to_rust_with_substitutions(&d.ty, address_map);
56 let ident = Ident::new(&format!("_{i}"), Span::call_site());
57 quote! (#ident: #ty)
58 })
59 };
60
61 let assign_args: &mut dyn Iterator<Item = TokenStream> = if self.is_empty() {
62 &mut std::iter::once(quote!(false))
63 } else {
64 &mut move_fields
65 .enumerate()
66 .map(|(i, _)| Ident::new(&format!("_{i}"), Span::call_site()).to_token_stream())
67 };
68
69 let phantom_data = phantoms.map(|_| quote!(::std::marker::PhantomData));
70
71 let args = quote!(#(#args),*);
72 let assignments = quote! {
73 (
74 #(#assign_args,)*
75 #( #phantom_data ),*
76 )
77 };
78 (args, assignments)
79 }
80}