1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Manifest {
8 pub manifest_id: String,
9 pub manifest_version: String,
10 pub application: ApplicationInfo,
11 pub build_graph: BuildGraph,
12 #[serde(default)]
13 pub build_targets: Vec<BuildTarget>,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub dependencies: Option<DependencyConfig>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct ApplicationInfo {
21 pub name: String,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 pub description: Option<String>,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 pub version: Option<String>,
26 #[serde(default)]
27 pub authors: Vec<String>,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 pub license: Option<String>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub repository: Option<String>,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct BuildGraph {
37 pub nodes: Vec<GraphNode>,
38 #[serde(default)]
39 pub edges: Vec<GraphEdge>,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct GraphNode {
45 pub id: String,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub source_cadi: Option<String>,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub ir_cadi: Option<String>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub blob_cadi: Option<String>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub container_cadi: Option<String>,
54 #[serde(default)]
55 pub representations: Vec<Representation>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub selection_strategy: Option<String>,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct Representation {
63 pub form: String,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub language: Option<String>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub format: Option<String>,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub architecture: Option<String>,
70 pub chunk: String,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct GraphEdge {
76 pub from: String,
77 pub to: String,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 pub interface: Option<String>,
80 #[serde(default = "default_relation")]
81 pub relation: String,
82}
83
84fn default_relation() -> String {
85 "depends_on".to_string()
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct BuildTarget {
91 pub name: String,
92 pub platform: String,
93 #[serde(default)]
94 pub nodes: Vec<TargetNode>,
95 #[serde(skip_serializing_if = "Option::is_none")]
96 pub bundle: Option<BundleConfig>,
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub deploy: Option<DeployConfig>,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct TargetNode {
104 pub id: String,
105 #[serde(skip_serializing_if = "Option::is_none")]
106 pub require: Option<Vec<String>>,
107 #[serde(skip_serializing_if = "Option::is_none")]
108 pub prefer: Option<Vec<String>>,
109}
110
111#[derive(Debug, Clone, Default, Serialize, Deserialize)]
113pub struct BundleConfig {
114 #[serde(skip_serializing_if = "Option::is_none")]
115 pub format: Option<String>,
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub output: Option<String>,
118 #[serde(default)]
119 pub minify: bool,
120}
121
122#[derive(Debug, Clone, Default, Serialize, Deserialize)]
124pub struct DeployConfig {
125 #[serde(skip_serializing_if = "Option::is_none")]
126 pub target: Option<String>,
127 #[serde(skip_serializing_if = "Option::is_none")]
128 pub replicas: Option<u32>,
129 #[serde(default)]
130 pub environment: std::collections::HashMap<String, String>,
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize)]
135pub struct DependencyConfig {
136 #[serde(skip_serializing_if = "Option::is_none")]
137 pub lock_file: Option<String>,
138 #[serde(default = "default_resolution_strategy")]
139 pub resolution_strategy: String,
140}
141
142fn default_resolution_strategy() -> String {
143 "newest".to_string()
144}
145
146impl Manifest {
147 pub fn new(manifest_id: String, app_name: String) -> Self {
149 Self {
150 manifest_id,
151 manifest_version: "1.0".to_string(),
152 application: ApplicationInfo {
153 name: app_name,
154 description: None,
155 version: None,
156 authors: Vec::new(),
157 license: None,
158 repository: None,
159 },
160 build_graph: BuildGraph {
161 nodes: Vec::new(),
162 edges: Vec::new(),
163 },
164 build_targets: Vec::new(),
165 dependencies: None,
166 }
167 }
168
169 pub fn add_node(&mut self, node: GraphNode) {
171 self.build_graph.nodes.push(node);
172 }
173
174 pub fn add_edge(&mut self, edge: GraphEdge) {
176 self.build_graph.edges.push(edge);
177 }
178
179 pub fn add_target(&mut self, target: BuildTarget) {
181 self.build_targets.push(target);
182 }
183
184 pub fn find_node(&self, id: &str) -> Option<&GraphNode> {
186 self.build_graph.nodes.iter().find(|n| n.id == id)
187 }
188
189 pub fn find_target(&self, name: &str) -> Option<&BuildTarget> {
191 self.build_targets.iter().find(|t| t.name == name)
192 }
193}