ploidy_codegen_rust/
cargo.rs

1use std::collections::{BTreeMap, BTreeSet};
2
3use cargo_toml::{Edition, Manifest};
4use itertools::Itertools;
5use ploidy_core::codegen::IntoCode;
6use serde::{Deserialize, Serialize};
7use toml::Value as TomlValue;
8
9use super::graph::CodegenGraph;
10
11type TomlMap = toml::map::Map<String, TomlValue>;
12
13const PLOIDY_VERSION: &str = env!("CARGO_PKG_VERSION");
14
15#[derive(Clone, Debug)]
16pub struct CodegenCargoManifest<'a> {
17    graph: &'a CodegenGraph<'a>,
18    manifest: &'a Manifest<CargoMetadata>,
19}
20
21impl<'a> CodegenCargoManifest<'a> {
22    #[inline]
23    pub fn new(graph: &'a CodegenGraph<'a>, manifest: &'a Manifest<CargoMetadata>) -> Self {
24        Self { graph, manifest }
25    }
26
27    pub fn to_manifest(self) -> Manifest<CargoMetadata> {
28        let mut manifest = self.manifest.clone();
29
30        // Ploidy generates Rust 2024-compatible code.
31        manifest
32            .package
33            .as_mut()
34            .unwrap()
35            .edition
36            .set(Edition::E2024);
37
38        let features = {
39            let names: BTreeSet<_> = self
40                .graph
41                .operations()
42                .map(|view| view.resource())
43                .filter(|&name| name != "full")
44                .collect();
45            let mut features: BTreeMap<_, _> = names
46                .iter()
47                .map(|&name| (name.to_owned(), vec![]))
48                .collect();
49            features.insert(
50                "full".to_owned(),
51                names.iter().map(|&name| name.to_owned()).collect_vec(),
52            );
53            features.insert("default".to_owned(), vec![]);
54            features
55        };
56
57        let dependencies = toml::toml! {
58            bytes = { version = "1", features = ["serde"] }
59            chrono = { version = "0.4", features = ["serde"] }
60            http = "1"
61            ploidy-util = PLOIDY_VERSION
62            reqwest = { version = "0.12", default-features = false, features = ["http2", "json", "multipart", "rustls-tls"] }
63            serde = { version = "1", features = ["derive"] }
64            serde_json = "1"
65            serde_path_to_error = "0.1"
66            thiserror = "2"
67            url = { version = "2.5", features = ["serde"] }
68            uuid = { version = "1", features = ["serde", "v4"] }
69        }.try_into().unwrap();
70
71        Manifest {
72            features,
73            dependencies,
74            ..manifest
75        }
76    }
77}
78
79impl IntoCode for CodegenCargoManifest<'_> {
80    type Code = (&'static str, Manifest<CargoMetadata>);
81
82    fn into_code(self) -> Self::Code {
83        ("Cargo.toml", self.to_manifest())
84    }
85}
86
87/// Cargo metadata of any type.
88#[derive(Clone, Debug, Deserialize, Serialize)]
89#[serde(transparent)]
90pub struct CargoMetadata(TomlValue);
91
92impl Default for CargoMetadata {
93    fn default() -> Self {
94        Self(TomlMap::default().into())
95    }
96}