Skip to main content

ploidy_codegen_rust/
lib.rs

1use std::{collections::BTreeMap, path::Path};
2
3use itertools::Itertools;
4use proc_macro2::TokenStream;
5use quote::quote;
6
7use ploidy_core::codegen::{IntoCode, write_to_disk};
8
9mod cargo;
10mod cfg;
11mod client;
12mod config;
13mod derives;
14mod enum_;
15mod ext;
16mod graph;
17mod inlines;
18mod naming;
19mod operation;
20mod primitive;
21mod query;
22mod ref_;
23mod resource;
24mod schema;
25mod statics;
26mod struct_;
27mod tagged;
28mod types;
29mod untagged;
30
31#[cfg(test)]
32mod tests;
33
34pub use cargo::*;
35pub use cfg::*;
36pub use client::*;
37pub use config::*;
38pub use graph::*;
39pub use naming::*;
40pub use operation::*;
41pub use primitive::*;
42pub use query::*;
43pub use resource::*;
44pub use schema::*;
45pub use statics::*;
46pub use types::*;
47
48pub fn write_types_to_disk(output: &Path, graph: &CodegenGraph<'_>) -> miette::Result<()> {
49    for schema in graph.schemas() {
50        let code = CodegenSchemaType::new(graph, &schema).into_code();
51        write_to_disk(output, code)?;
52    }
53
54    write_to_disk(output, CodegenTypesModule::new(graph))?;
55
56    Ok(())
57}
58
59pub fn write_client_to_disk(output: &Path, graph: &CodegenGraph<'_>) -> miette::Result<()> {
60    // Group operations by resource name.
61    let ops_by_resource: BTreeMap<_, Vec<_>> =
62        graph.operations().fold(BTreeMap::default(), |mut map, op| {
63            let resource = graph.resource_for(&op);
64            map.entry(resource).or_default().push(op);
65            map
66        });
67
68    // Write a module per resource.
69    for (ident, ops) in &ops_by_resource {
70        write_to_disk(output, CodegenResource::new(graph, *ident, ops))?;
71    }
72
73    // Write the top-level client module.
74    let idents = ops_by_resource.keys().copied().collect_vec();
75    write_to_disk(output, CodegenClientModule::new(graph, &idents))?;
76
77    Ok(())
78}
79
80/// Generates one or more `#[doc]` attributes for a schema description,
81/// wrapping at 80 characters for readability.
82pub fn doc_attrs(description: &str) -> TokenStream {
83    let lines = textwrap::wrap(description, 80)
84        .into_iter()
85        .map(|line| quote!(#[doc = #line]));
86    quote! { #(#lines)* }
87}