Skip to main content

ploidy_codegen_rust/
types.rs

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