actr_web_protoc_codegen/
request.rs1use serde::{Deserialize, Serialize};
7use std::path::PathBuf;
8
9#[derive(Debug, Serialize, Deserialize)]
11pub struct WebCodegenRequest {
12 pub config_path: PathBuf,
14 pub output_dir: PathBuf,
16 pub project_root: PathBuf,
18 pub overwrite_user_code: bool,
20
21 pub package_name: String,
23 pub manufacturer: String,
24 pub actr_name: String,
25 #[serde(default)]
26 pub version: String,
27 pub description: String,
28 pub authors: Vec<String>,
29 pub license: String,
30 pub tags: Vec<String>,
31
32 pub signaling_url: String,
34 pub realm_id: u32,
35 pub visible_in_discovery: bool,
36
37 #[serde(default)]
39 pub ais_endpoint: String,
40
41 #[serde(default)]
43 pub force_relay: bool,
44
45 pub dependencies: Vec<DependencyInfo>,
47
48 pub stun_urls: Vec<String>,
50 pub turn_urls: Vec<String>,
51
52 pub observability: ObservabilityInfo,
54
55 pub raw_toml: String,
57
58 pub local_services: Vec<ServiceInfo>,
60 pub remote_services: Vec<ServiceInfo>,
61 pub files: Vec<FileInfo>,
62}
63
64#[derive(Debug, Serialize, Deserialize)]
65pub struct DependencyInfo {
66 pub alias: String,
67 pub actr_type: Option<ActrTypeInfo>,
68}
69
70#[derive(Debug, Serialize, Deserialize)]
71pub struct ActrTypeInfo {
72 pub manufacturer: String,
73 pub name: String,
74 #[serde(default)]
75 pub version: String,
76}
77
78#[derive(Debug, Serialize, Deserialize)]
79pub struct ObservabilityInfo {
80 pub filter_level: String,
81 pub tracing_enabled: bool,
82 pub tracing_endpoint: String,
83 pub tracing_service_name: String,
84}
85
86#[derive(Debug, Serialize, Deserialize)]
87pub struct ServiceInfo {
88 pub name: String,
89 pub package: String,
90 pub relative_path: PathBuf,
91 pub methods: Vec<MethodInfo>,
92 pub actr_type: Option<String>,
93}
94
95#[derive(Debug, Serialize, Deserialize)]
96pub struct MethodInfo {
97 pub name: String,
98 pub snake_name: String,
99 pub input_type: String,
100 pub output_type: String,
101 pub route_key: String,
102}
103
104#[derive(Debug, Serialize, Deserialize)]
105pub struct FileInfo {
106 pub proto_file: PathBuf,
107 pub relative_path: PathBuf,
108 pub package: String,
109 pub is_local: bool,
110 pub declared_type_names: Vec<String>,
111}
112
113#[derive(Debug, Serialize, Deserialize)]
115pub struct WebCodegenResponse {
116 pub success: bool,
117 pub generated_files: Vec<PathBuf>,
118 pub errors: Vec<String>,
119}
120
121impl WebCodegenRequest {
122 pub fn is_service_provider_only(&self) -> bool {
131 !self.local_services.is_empty()
132 && self.remote_services.is_empty()
133 && self.dependencies.is_empty()
134 }
135
136 pub fn get_acl_allow_types(&self) -> Vec<String> {
138 let raw_table: toml::Table = self.raw_toml.parse().unwrap_or_default();
139 let mut types = Vec::new();
140 if let Some(acl) = raw_table.get("acl") {
141 if let Some(rules) = acl.get("rules").and_then(|r| r.as_array()) {
142 for rule in rules {
143 if let Some(rule_types) = rule.get("types").and_then(|t| t.as_array()) {
144 for t in rule_types {
145 if let Some(s) = t.as_str() {
146 types.push(s.to_string());
147 }
148 }
149 }
150 }
151 }
152 }
153 types
154 }
155
156 pub fn target_actr_type(&self) -> String {
163 if self.is_service_provider_only() {
164 self.get_acl_allow_types()
165 .first()
166 .cloned()
167 .unwrap_or_default()
168 } else {
169 self.dependencies
170 .first()
171 .and_then(|d| {
172 d.actr_type
173 .as_ref()
174 .map(|t| format!("{}:{}:{}", t.manufacturer, t.name, t.version))
175 })
176 .unwrap_or_default()
177 }
178 }
179
180 pub fn client_actr_type(&self) -> String {
182 format!("{}:{}:{}", self.manufacturer, self.actr_name, self.version)
183 }
184
185 pub fn wasm_module_name(&self) -> String {
187 to_snake_case(&self.package_name).replace('-', "_")
188 }
189
190 pub fn edition(&self) -> i64 {
192 let raw_table: toml::Table = self.raw_toml.parse().unwrap_or_default();
193 raw_table
194 .get("edition")
195 .and_then(|v| v.as_integer())
196 .unwrap_or(1)
197 }
198
199 pub fn exports_list(&self) -> Vec<String> {
201 let raw_table: toml::Table = self.raw_toml.parse().unwrap_or_default();
202 raw_table
203 .get("exports")
204 .and_then(|v| v.as_array())
205 .map(|arr| {
206 arr.iter()
207 .filter_map(|v| v.as_str().map(String::from))
208 .collect()
209 })
210 .unwrap_or_default()
211 }
212
213 pub fn platform_web(&self) -> Option<toml::Value> {
215 let raw_table: toml::Table = self.raw_toml.parse().unwrap_or_default();
216 raw_table
217 .get("platform")
218 .and_then(|v| v.get("web"))
219 .cloned()
220 }
221
222 pub fn raw_acl(&self) -> Option<toml::Value> {
224 let raw_table: toml::Table = self.raw_toml.parse().unwrap_or_default();
225 raw_table.get("acl").cloned()
226 }
227}
228
229fn to_snake_case(name: &str) -> String {
230 use heck::ToSnakeCase;
231 name.to_snake_case()
232}