AtsRustCodeGenerator.cs (186)
107WriteLine("//! aspire.rs - Capability-based Aspire SDK");
108WriteLine("//! GENERATED CODE - DO NOT EDIT");
109WriteLine();
110WriteLine("use std::collections::HashMap;");
111WriteLine("use std::sync::Arc;");
112WriteLine();
113WriteLine("use serde::{Deserialize, Serialize};");
114WriteLine("use serde_json::{json, Value};");
115WriteLine();
116WriteLine("use crate::transport::{");
117WriteLine(" AspireClient, CancellationToken, Handle,");
118WriteLine(" register_callback, register_cancellation, serialize_value,");
119WriteLine("};");
120WriteLine("use crate::base::{");
121WriteLine(" HandleWrapperBase, ResourceBuilderBase, ReferenceExpression,");
122WriteLine(" AspireList, AspireDict, serialize_handle, HasHandle,");
123WriteLine("};");
124WriteLine();
134WriteLine("// ============================================================================");
135WriteLine("// Enums");
136WriteLine("// ============================================================================");
137WriteLine();
147WriteLine($"/// {enumType.Name}");
148WriteLine("#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]");
149WriteLine($"pub enum {enumName} {{");
156WriteLine($" #[default]");
159WriteLine($" #[serde(rename = \"{member}\")]");
160WriteLine($" {memberName},");
162WriteLine("}");
163WriteLine();
166WriteLine($"impl std::fmt::Display for {enumName} {{");
167WriteLine(" fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {");
168WriteLine(" match self {");
172WriteLine($" Self::{memberName} => write!(f, \"{member}\"),");
174WriteLine(" }");
175WriteLine(" }");
176WriteLine("}");
177WriteLine();
188WriteLine("// ============================================================================");
189WriteLine("// DTOs");
190WriteLine("// ============================================================================");
191WriteLine();
202WriteLine($"/// {dto.Name}");
203WriteLine("#[derive(Debug, Clone, Default, Serialize, Deserialize)]");
204WriteLine($"pub struct {dtoName} {{");
211WriteLine($" #[serde(rename = \"{property.Name}\", skip_serializing_if = \"Option::is_none\")]");
215WriteLine($" #[serde(rename = \"{property.Name}\")]");
217WriteLine($" pub {propertyName}: {propertyType},");
219WriteLine("}");
220WriteLine();
223WriteLine($"impl {dtoName} {{");
224WriteLine(" pub fn to_map(&self) -> HashMap<String, Value> {");
225WriteLine(" let mut map = HashMap::new();");
231WriteLine($" if let Some(ref v) = self.{propertyName} {{");
232WriteLine($" map.insert(\"{property.Name}\".to_string(), serde_json::to_value(v).unwrap_or(Value::Null));");
233WriteLine(" }");
237WriteLine($" map.insert(\"{property.Name}\".to_string(), serde_json::to_value(&self.{propertyName}).unwrap_or(Value::Null));");
240WriteLine(" map");
241WriteLine(" }");
242WriteLine("}");
243WriteLine();
256WriteLine("// ============================================================================");
257WriteLine("// Handle Wrappers");
258WriteLine("// ============================================================================");
259WriteLine();
263WriteLine($"/// Wrapper for {handleType.TypeId}");
264WriteLine($"pub struct {handleType.StructName} {{");
265WriteLine(" handle: Handle,");
266WriteLine(" client: Arc<AspireClient>,");
267WriteLine("}");
268WriteLine();
271WriteLine($"impl HasHandle for {handleType.StructName} {{");
272WriteLine(" fn handle(&self) -> &Handle {");
273WriteLine(" &self.handle");
274WriteLine(" }");
275WriteLine("}");
276WriteLine();
279WriteLine($"impl {handleType.StructName} {{");
280WriteLine(" pub fn new(handle: Handle, client: Arc<AspireClient>) -> Self {");
281WriteLine(" Self { handle, client }");
282WriteLine(" }");
283WriteLine();
284WriteLine(" pub fn handle(&self) -> &Handle {");
285WriteLine(" &self.handle");
286WriteLine(" }");
287WriteLine();
288WriteLine(" pub fn client(&self) -> &Arc<AspireClient> {");
289WriteLine(" &self.client");
290WriteLine(" }");
300WriteLine("}");
301WriteLine();
355WriteLine();
356WriteLine($" /// {capability.Description}");
360WriteLine($" pub fn {methodName}({paramList}) -> {resultType} {{");
361WriteLine(" let mut args: HashMap<String, Value> = HashMap::new();");
362WriteLine($" args.insert(\"{targetParamName}\".to_string(), self.handle.to_json());");
369WriteLine($" let callback_id = register_callback({paramName});");
370WriteLine($" args.insert(\"{parameter.Name}\".to_string(), Value::String(callback_id));");
376WriteLine($" if let Some(token) = {paramName} {{");
377WriteLine($" let token_id = register_cancellation(token, self.client.clone());");
378WriteLine($" args.insert(\"{parameter.Name}\".to_string(), Value::String(token_id));");
379WriteLine(" }");
388WriteLine($" if let Some(ref v) = {paramName} {{");
389WriteLine($" args.insert(\"{parameter.Name}\".to_string(), v.handle().to_json());");
390WriteLine(" }");
394WriteLine($" args.insert(\"{parameter.Name}\".to_string(), {paramName}.handle().to_json());");
404WriteLine($" if let Some(ref v) = {paramName} {{");
405WriteLine($" args.insert(\"{parameter.Name}\".to_string(), v.handle().to_json());");
406WriteLine(" }");
410WriteLine($" args.insert(\"{parameter.Name}\".to_string(), {paramName}.handle().to_json());");
420WriteLine($" if let Some(ref v) = {paramName} {{");
421WriteLine($" let handles: Vec<Value> = v.iter().map(|item| item.handle().to_json()).collect();");
422WriteLine($" args.insert(\"{parameter.Name}\".to_string(), Value::Array(handles));");
423WriteLine(" }");
427WriteLine($" let handles: Vec<Value> = {paramName}.iter().map(|item| item.handle().to_json()).collect();");
428WriteLine($" args.insert(\"{parameter.Name}\".to_string(), Value::Array(handles));");
435WriteLine($" if let Some(ref v) = {paramName} {{");
436WriteLine($" args.insert(\"{parameter.Name}\".to_string(), serde_json::to_value(v).unwrap_or(Value::Null));");
437WriteLine(" }");
441WriteLine($" args.insert(\"{parameter.Name}\".to_string(), serde_json::to_value(&{paramName}).unwrap_or(Value::Null));");
445WriteLine($" let result = self.client.invoke_capability(\"{capability.CapabilityId}\", args)?;");
455WriteLine($" let handle: Handle = serde_json::from_value(result)?;");
456WriteLine($" Ok({wrappedType}::new(handle, self.client.clone()))");
461WriteLine($" let handle: Handle = serde_json::from_value(result)?;");
462WriteLine($" Ok(CancellationToken::new(handle, self.client.clone()))");
467WriteLine($" let handle: Handle = serde_json::from_value(result)?;");
468WriteLine($" Ok(AspireDict::new(handle, self.client.clone()))");
473WriteLine($" let handle: Handle = serde_json::from_value(result)?;");
474WriteLine($" Ok(AspireList::new(handle, self.client.clone()))");
480WriteLine($" let handles: Vec<Handle> = serde_json::from_value(result)?;");
481WriteLine($" Ok(handles.into_iter().map(|h| {elementType}::new(h, self.client.clone())).collect())");
485WriteLine($" Ok(serde_json::from_value(result)?)");
490WriteLine(" Ok(())");
493WriteLine(" }");
533WriteLine();
534WriteLine($" /// {capability.Description}");
538WriteLine($" pub fn {methodName}(&self) -> {fullType} {{");
539WriteLine($" {wrapperType}::with_getter(self.handle.clone(), self.client.clone(), \"{capability.CapabilityId}\")");
540WriteLine(" }");
549WriteLine("// ============================================================================");
550WriteLine("// Handle wrapper registrations");
551WriteLine("// ============================================================================");
552WriteLine();
553WriteLine("pub fn register_all_wrappers() {");
554WriteLine(" // Handle wrappers are created inline in generated code");
555WriteLine(" // This function is provided for API compatibility");
556WriteLine("}");
557WriteLine();
566WriteLine("// ============================================================================");
567WriteLine("// Connection Helpers");
568WriteLine("// ============================================================================");
569WriteLine();
570WriteLine("/// Establishes a connection to the AppHost server.");
571WriteLine("pub fn connect() -> Result<Arc<AspireClient>, Box<dyn std::error::Error>> {");
572WriteLine(" let socket_path = std::env::var(\"REMOTE_APP_HOST_SOCKET_PATH\")");
573WriteLine(" .map_err(|_| \"REMOTE_APP_HOST_SOCKET_PATH environment variable not set. Run this application using `aspire run`\")?;");
574WriteLine(" let client = Arc::new(AspireClient::new(&socket_path));");
575WriteLine(" client.connect()?;");
576WriteLine(" Ok(client)");
577WriteLine("}");
578WriteLine();
579WriteLine($"/// Creates a new distributed application builder.");
580WriteLine($"pub fn create_builder(options: Option<CreateBuilderOptions>) -> Result<{builderStructName}, Box<dyn std::error::Error>> {{");
581WriteLine(" let client = connect()?;");
582WriteLine(" let mut resolved_options: HashMap<String, Value> = HashMap::new();");
583WriteLine(" if let Some(opts) = options {");
584WriteLine(" for (k, v) in opts.to_map() {");
585WriteLine(" resolved_options.insert(k, v);");
586WriteLine(" }");
587WriteLine(" }");
588WriteLine(" if !resolved_options.contains_key(\"Args\") {");
589WriteLine(" let args: Vec<String> = std::env::args().skip(1).collect();");
590WriteLine(" resolved_options.insert(\"Args\".to_string(), serde_json::to_value(args).unwrap_or(Value::Null));");
591WriteLine(" }");
592WriteLine(" if !resolved_options.contains_key(\"ProjectDirectory\") {");
593WriteLine(" if let Ok(pwd) = std::env::current_dir() {");
594WriteLine(" resolved_options.insert(\"ProjectDirectory\".to_string(), Value::String(pwd.to_string_lossy().to_string()));");
595WriteLine(" }");
596WriteLine(" }");
597WriteLine(" let mut args: HashMap<String, Value> = HashMap::new();");
598WriteLine(" args.insert(\"options\".to_string(), serde_json::to_value(resolved_options).unwrap_or(Value::Null));");
599WriteLine(" let result = client.invoke_capability(\"Aspire.Hosting/createBuilderWithOptions\", args)?;");
600WriteLine(" let handle: Handle = serde_json::from_value(result)?;");
601WriteLine($" Ok({builderStructName}::new(handle, client))");
602WriteLine("}");
603WriteLine();