ploidy_codegen_rust/
schema.rs1use ploidy_core::{
2 codegen::IntoCode,
3 ir::{InlineIrTypeView, SchemaIrTypeView, View},
4};
5use proc_macro2::TokenStream;
6use quote::{ToTokens, TokenStreamExt, quote};
7
8use super::{
9 enum_::CodegenEnum,
10 naming::{CodegenIdent, CodegenIdentUsage, CodegenTypeName},
11 struct_::CodegenStruct,
12 tagged::CodegenTagged,
13 untagged::CodegenUntagged,
14};
15
16#[derive(Debug)]
18pub struct CodegenSchemaType<'a> {
19 ty: &'a SchemaIrTypeView<'a>,
20}
21
22impl<'a> CodegenSchemaType<'a> {
23 pub fn new(ty: &'a SchemaIrTypeView<'a>) -> Self {
24 Self { ty }
25 }
26}
27
28impl ToTokens for CodegenSchemaType<'_> {
29 fn to_tokens(&self, tokens: &mut TokenStream) {
30 let name = CodegenTypeName::Schema(self.ty);
31 let code = match self.ty {
32 SchemaIrTypeView::Struct(_, view) => CodegenStruct::new(name, view).into_token_stream(),
33 SchemaIrTypeView::Enum(_, view) => CodegenEnum::new(name, view).into_token_stream(),
34 SchemaIrTypeView::Tagged(_, view) => CodegenTagged::new(name, view).into_token_stream(),
35 SchemaIrTypeView::Untagged(_, view) => {
36 CodegenUntagged::new(name, view).into_token_stream()
37 }
38 };
39 let mut inlines = self.ty.inlines().map(|view| {
40 let name = CodegenTypeName::Inline(&view);
41 match &view {
42 InlineIrTypeView::Enum(_, view) => CodegenEnum::new(name, view).into_token_stream(),
43 InlineIrTypeView::Struct(_, view) => {
44 CodegenStruct::new(name, view).into_token_stream()
45 }
46 InlineIrTypeView::Tagged(_, view) => {
47 CodegenTagged::new(name, view).into_token_stream()
48 }
49 InlineIrTypeView::Untagged(_, view) => {
50 CodegenUntagged::new(name, view).into_token_stream()
51 }
52 }
53 });
54 let fields_module = inlines.next().map(|head| {
55 quote! {
56 pub mod types {
57 #head
58 #(#inlines)*
59 }
60 }
61 });
62 tokens.append_all(quote! {
63 #code
64 #fields_module
65 });
66 }
67}
68
69impl IntoCode for CodegenSchemaType<'_> {
70 type Code = (String, TokenStream);
71
72 fn into_code(self) -> Self::Code {
73 let ident = self.ty.extensions().get::<CodegenIdent>().unwrap();
74 let usage = CodegenIdentUsage::Module(&ident);
75 (format!("src/types/{usage}.rs"), self.into_token_stream())
76 }
77}