Skip to main content

ploidy_codegen_rust/
types.rs

1use itertools::Itertools;
2use ploidy_core::codegen::IntoCode;
3use proc_macro2::TokenStream;
4use quote::{ToTokens, TokenStreamExt, quote};
5
6use super::{
7    cfg::CfgFeature,
8    graph::CodegenGraph,
9    naming::{CodegenTypeName, CodegenTypeNameSortKey},
10};
11
12/// Generates the `types/mod.rs` module.
13pub struct CodegenTypesModule<'a> {
14    graph: &'a CodegenGraph<'a>,
15}
16
17impl<'a> CodegenTypesModule<'a> {
18    pub fn new(graph: &'a CodegenGraph<'a>) -> Self {
19        Self { graph }
20    }
21}
22
23impl ToTokens for CodegenTypesModule<'_> {
24    fn to_tokens(&self, tokens: &mut TokenStream) {
25        let mut tys = self.graph.schemas().collect_vec();
26        tys.sort_by(|a, b| {
27            CodegenTypeNameSortKey::for_schema(a).cmp(&CodegenTypeNameSortKey::for_schema(b))
28        });
29
30        let mods = tys.iter().map(|ty| {
31            let cfg = CfgFeature::for_schema_type(ty);
32            let mod_name = CodegenTypeName::Schema(ty).into_module_name();
33            quote! {
34                #cfg
35                pub mod #mod_name;
36            }
37        });
38        let uses = tys.iter().map(|ty| {
39            let cfg = CfgFeature::for_schema_type(ty);
40            let ty_name = CodegenTypeName::Schema(ty);
41            let mod_name = ty_name.into_module_name();
42            quote! {
43                #cfg
44                pub use #mod_name::#ty_name;
45            }
46        });
47
48        tokens.append_all(quote! {
49            #(#mods)*
50            #(#uses)*
51        });
52    }
53}
54
55impl IntoCode for CodegenTypesModule<'_> {
56    type Code = (&'static str, TokenStream);
57
58    fn into_code(self) -> Self::Code {
59        ("src/types/mod.rs", self.into_token_stream())
60    }
61}