ploidy_codegen_rust/
resource.rs1use heck::ToSnakeCase;
2use ploidy_core::{
3 codegen::IntoCode,
4 ir::{InlineIrTypePathRoot, InlineIrTypeView, IrOperationView},
5};
6use proc_macro2::TokenStream;
7use quote::{ToTokens, TokenStreamExt, quote};
8
9use super::{
10 enum_::CodegenEnum, naming::CodegenTypeName, operation::CodegenOperation,
11 struct_::CodegenStruct, untagged::CodegenUntagged,
12};
13
14pub struct CodegenResource<'a> {
17 resource: &'a str,
18 operations: &'a [IrOperationView<'a>],
19}
20
21impl<'a> CodegenResource<'a> {
22 pub fn new(resource: &'a str, operations: &'a [IrOperationView<'a>]) -> Self {
23 Self {
24 resource,
25 operations,
26 }
27 }
28}
29
30impl ToTokens for CodegenResource<'_> {
31 fn to_tokens(&self, tokens: &mut TokenStream) {
32 let feature_name = self.resource;
33 let methods: Vec<TokenStream> = self
34 .operations
35 .iter()
36 .map(|view| CodegenOperation::new(view).into_token_stream())
37 .collect();
38
39 let mut inlines = self
40 .operations
41 .iter()
42 .flat_map(|op| op.inlines())
43 .filter(|ty| {
44 matches!(ty.path().root, InlineIrTypePathRoot::Resource(r) if r == self.resource)
49 })
50 .map(|view| match view {
51 InlineIrTypeView::Enum(path, view) => {
52 CodegenEnum::new(CodegenTypeName::Inline(path), &view).into_token_stream()
53 }
54 InlineIrTypeView::Struct(path, view) => {
55 CodegenStruct::new(CodegenTypeName::Inline(path), &view).into_token_stream()
56 }
57 InlineIrTypeView::Untagged(path, view) => {
58 CodegenUntagged::new(CodegenTypeName::Inline(path), &view).into_token_stream()
59 }
60 });
61 let fields_module = inlines.next().map(|head| {
62 quote! {
63 pub mod types {
64 #head
65 #(#inlines)*
66 }
67 }
68 });
69
70 tokens.append_all(quote! {
71 #[cfg(feature = #feature_name)]
72 impl crate::client::Client {
73 #(#methods)*
74 }
75 #fields_module
76 });
77 }
78}
79
80impl IntoCode for CodegenResource<'_> {
81 type Code = (String, TokenStream);
82
83 fn into_code(self) -> Self::Code {
84 (
85 format!("src/client/{}.rs", self.resource.to_snake_case()),
86 self.into_token_stream(),
87 )
88 }
89}