moverox_codegen/
lib.rs

1#![cfg_attr(all(doc, not(doctest)), feature(doc_auto_cfg))]
2
3//! Generate Rust code from Move IR parsed by move-syn.
4//!
5//! Defines extension traits to generate Rust code from Move intermediate representation.
6//!
7//! `thecrate` in arguments here is the path to a crate/module which exports:
8//! - a `types` module with `Address` and `U256` types from `moverox-types`
9//! - a `traits` module with `HasKey`, `MoveDatatype` and `MoveType` traits from `moverox-traits`
10//! - the `serde` crate
11
12use std::collections::HashMap;
13
14use move_syn::{Item, Module};
15use proc_macro2::{Ident, TokenStream};
16use quote::quote;
17use unsynn::LiteralString;
18
19mod attributes;
20mod generics;
21mod move_enum;
22mod move_struct;
23mod move_type;
24mod named_fields;
25mod positional_fields;
26#[cfg(test)]
27mod tests;
28
29use self::move_struct::StructGen as _;
30
31#[sealed::sealed]
32pub trait ModuleGen {
33    fn to_rust(
34        &self,
35        thecrate: &TokenStream,
36        package: Option<&LiteralString>,
37        address_map: &HashMap<Ident, TokenStream>,
38    ) -> TokenStream;
39}
40
41#[sealed::sealed]
42impl ModuleGen for Module {
43    fn to_rust(
44        &self,
45        thecrate: &TokenStream,
46        package: Option<&LiteralString>,
47        address_map: &HashMap<Ident, TokenStream>,
48    ) -> TokenStream {
49        let attrs = crate::attributes::to_rust(&self.attrs);
50        let ident = &self.ident;
51        let datatypes: TokenStream = self
52            .items()
53            .map(|item| item.to_rust(thecrate, package, Some(ident), address_map))
54            .collect();
55        quote! {
56            #attrs
57            #[allow(rustdoc::all)]
58            pub mod #ident {
59                #[allow(non_camel_case_types, unused)]
60                type address = #thecrate::types::Address;
61                #[allow(non_camel_case_types, unused)]
62                type u256 = #thecrate::types::U256;
63                #[allow(non_camel_case_types, unused)]
64                type vector<T> = ::std::vec::Vec<T>;
65
66                #datatypes
67            }
68        }
69    }
70}
71
72#[sealed::sealed]
73pub trait ItemGen {
74    fn to_rust(
75        &self,
76        thecrate: &TokenStream,
77        package: Option<&LiteralString>,
78        module: Option<&Ident>,
79        address_map: &HashMap<Ident, TokenStream>,
80    ) -> TokenStream;
81}
82
83#[sealed::sealed]
84impl ItemGen for Item {
85    fn to_rust(
86        &self,
87        thecrate: &TokenStream,
88        package: Option<&LiteralString>,
89        module: Option<&Ident>,
90        address_map: &HashMap<Ident, TokenStream>,
91    ) -> TokenStream {
92        use move_syn::ItemKind as K;
93        let Self { attrs, kind, .. } = self;
94        let generated = match kind {
95            K::Struct(s) => s.to_rust(thecrate, package, module, address_map),
96            K::Enum(e) => self::move_enum::to_rust(e, thecrate, package, module, address_map),
97            _ => return Default::default(),
98        };
99        let attrs = crate::attributes::to_rust(attrs);
100        quote! {
101            #attrs
102            #generated
103        }
104    }
105}