AtsRustCodeGenerator.cs (174)
108WriteLine("//! aspire.rs - Capability-based Aspire SDK");
109WriteLine("//! GENERATED CODE - DO NOT EDIT");
110WriteLine();
111WriteLine("use std::collections::HashMap;");
112WriteLine("use std::sync::Arc;");
113WriteLine();
114WriteLine("use serde::{Deserialize, Serialize};");
115WriteLine("use serde_json::{json, Value};");
116WriteLine();
117WriteLine("use crate::transport::{");
118WriteLine(" AspireClient, CancellationToken, Handle,");
119WriteLine(" register_callback, register_cancellation, serialize_value,");
120WriteLine("};");
121WriteLine("use crate::base::{");
122WriteLine(" HandleWrapperBase, ResourceBuilderBase, ReferenceExpression,");
123WriteLine(" AspireList, AspireDict, serialize_handle, HasHandle,");
124WriteLine("};");
125WriteLine();
135WriteLine("// ============================================================================");
136WriteLine("// Enums");
137WriteLine("// ============================================================================");
138WriteLine();
148WriteLine($"/// {enumType.Name}");
149WriteLine("#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]");
150WriteLine($"pub enum {enumName} {{");
157WriteLine($" #[default]");
160WriteLine($" #[serde(rename = \"{member}\")]");
161WriteLine($" {memberName},");
163WriteLine("}");
164WriteLine();
167WriteLine($"impl std::fmt::Display for {enumName} {{");
168WriteLine(" fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {");
169WriteLine(" match self {");
173WriteLine($" Self::{memberName} => write!(f, \"{member}\"),");
175WriteLine(" }");
176WriteLine(" }");
177WriteLine("}");
178WriteLine();
189WriteLine("// ============================================================================");
190WriteLine("// DTOs");
191WriteLine("// ============================================================================");
192WriteLine();
203WriteLine($"/// {dto.Name}");
204WriteLine("#[derive(Debug, Clone, Default, Serialize, Deserialize)]");
205WriteLine($"pub struct {dtoName} {{");
212WriteLine($" #[serde(rename = \"{property.Name}\", skip_serializing_if = \"Option::is_none\")]");
216WriteLine($" #[serde(rename = \"{property.Name}\")]");
218WriteLine($" pub {propertyName}: {propertyType},");
220WriteLine("}");
221WriteLine();
224WriteLine($"impl {dtoName} {{");
225WriteLine(" pub fn to_map(&self) -> HashMap<String, Value> {");
226WriteLine(" let mut map = HashMap::new();");
232WriteLine($" if let Some(ref v) = self.{propertyName} {{");
233WriteLine($" map.insert(\"{property.Name}\".to_string(), serde_json::to_value(v).unwrap_or(Value::Null));");
234WriteLine(" }");
238WriteLine($" map.insert(\"{property.Name}\".to_string(), serde_json::to_value(&self.{propertyName}).unwrap_or(Value::Null));");
241WriteLine(" map");
242WriteLine(" }");
243WriteLine("}");
244WriteLine();
257WriteLine("// ============================================================================");
258WriteLine("// Handle Wrappers");
259WriteLine("// ============================================================================");
260WriteLine();
264WriteLine($"/// Wrapper for {handleType.TypeId}");
265WriteLine($"pub struct {handleType.StructName} {{");
266WriteLine(" handle: Handle,");
267WriteLine(" client: Arc<AspireClient>,");
268WriteLine("}");
269WriteLine();
272WriteLine($"impl HasHandle for {handleType.StructName} {{");
273WriteLine(" fn handle(&self) -> &Handle {");
274WriteLine(" &self.handle");
275WriteLine(" }");
276WriteLine("}");
277WriteLine();
280WriteLine($"impl {handleType.StructName} {{");
281WriteLine(" pub fn new(handle: Handle, client: Arc<AspireClient>) -> Self {");
282WriteLine(" Self { handle, client }");
283WriteLine(" }");
284WriteLine();
285WriteLine(" pub fn handle(&self) -> &Handle {");
286WriteLine(" &self.handle");
287WriteLine(" }");
288WriteLine();
289WriteLine(" pub fn client(&self) -> &Arc<AspireClient> {");
290WriteLine(" &self.client");
291WriteLine(" }");
301WriteLine("}");
302WriteLine();
356WriteLine();
357WriteLine($" /// {capability.Description}");
361WriteLine($" pub fn {methodName}({paramList}) -> {resultType} {{");
362WriteLine(" let mut args: HashMap<String, Value> = HashMap::new();");
363WriteLine($" args.insert(\"{targetParamName}\".to_string(), self.handle.to_json());");
370WriteLine($" let callback_id = register_callback({paramName});");
371WriteLine($" args.insert(\"{parameter.Name}\".to_string(), Value::String(callback_id));");
377WriteLine($" if let Some(token) = {paramName} {{");
378WriteLine($" let token_id = register_cancellation(token, self.client.clone());");
379WriteLine($" args.insert(\"{parameter.Name}\".to_string(), Value::String(token_id));");
380WriteLine(" }");
389WriteLine($" if let Some(ref v) = {paramName} {{");
390WriteLine($" args.insert(\"{parameter.Name}\".to_string(), v.handle().to_json());");
391WriteLine(" }");
395WriteLine($" args.insert(\"{parameter.Name}\".to_string(), {paramName}.handle().to_json());");
402WriteLine($" if let Some(ref v) = {paramName} {{");
403WriteLine($" args.insert(\"{parameter.Name}\".to_string(), serde_json::to_value(v).unwrap_or(Value::Null));");
404WriteLine(" }");
408WriteLine($" args.insert(\"{parameter.Name}\".to_string(), serde_json::to_value(&{paramName}).unwrap_or(Value::Null));");
412WriteLine($" let result = self.client.invoke_capability(\"{capability.CapabilityId}\", args)?;");
422WriteLine($" let handle: Handle = serde_json::from_value(result)?;");
423WriteLine($" Ok({wrappedType}::new(handle, self.client.clone()))");
428WriteLine($" let handle: Handle = serde_json::from_value(result)?;");
429WriteLine($" Ok(CancellationToken::new(handle, self.client.clone()))");
434WriteLine($" let handle: Handle = serde_json::from_value(result)?;");
435WriteLine($" Ok(AspireDict::new(handle, self.client.clone()))");
440WriteLine($" let handle: Handle = serde_json::from_value(result)?;");
441WriteLine($" Ok(AspireList::new(handle, self.client.clone()))");
445WriteLine($" Ok(serde_json::from_value(result)?)");
450WriteLine(" Ok(())");
453WriteLine(" }");
493WriteLine();
494WriteLine($" /// {capability.Description}");
498WriteLine($" pub fn {methodName}(&self) -> {fullType} {{");
499WriteLine($" {wrapperType}::with_getter(self.handle.clone(), self.client.clone(), \"{capability.CapabilityId}\")");
500WriteLine(" }");
509WriteLine("// ============================================================================");
510WriteLine("// Handle wrapper registrations");
511WriteLine("// ============================================================================");
512WriteLine();
513WriteLine("pub fn register_all_wrappers() {");
514WriteLine(" // Handle wrappers are created inline in generated code");
515WriteLine(" // This function is provided for API compatibility");
516WriteLine("}");
517WriteLine();
526WriteLine("// ============================================================================");
527WriteLine("// Connection Helpers");
528WriteLine("// ============================================================================");
529WriteLine();
530WriteLine("/// Establishes a connection to the AppHost server.");
531WriteLine("pub fn connect() -> Result<Arc<AspireClient>, Box<dyn std::error::Error>> {");
532WriteLine(" let socket_path = std::env::var(\"REMOTE_APP_HOST_SOCKET_PATH\")");
533WriteLine(" .map_err(|_| \"REMOTE_APP_HOST_SOCKET_PATH environment variable not set. Run this application using `aspire run`\")?;");
534WriteLine(" let client = Arc::new(AspireClient::new(&socket_path));");
535WriteLine(" client.connect()?;");
536WriteLine(" Ok(client)");
537WriteLine("}");
538WriteLine();
539WriteLine($"/// Creates a new distributed application builder.");
540WriteLine($"pub fn create_builder(options: Option<CreateBuilderOptions>) -> Result<{builderStructName}, Box<dyn std::error::Error>> {{");
541WriteLine(" let client = connect()?;");
542WriteLine(" let mut resolved_options: HashMap<String, Value> = HashMap::new();");
543WriteLine(" if let Some(opts) = options {");
544WriteLine(" for (k, v) in opts.to_map() {");
545WriteLine(" resolved_options.insert(k, v);");
546WriteLine(" }");
547WriteLine(" }");
548WriteLine(" if !resolved_options.contains_key(\"Args\") {");
549WriteLine(" let args: Vec<String> = std::env::args().skip(1).collect();");
550WriteLine(" resolved_options.insert(\"Args\".to_string(), serde_json::to_value(args).unwrap_or(Value::Null));");
551WriteLine(" }");
552WriteLine(" if !resolved_options.contains_key(\"ProjectDirectory\") {");
553WriteLine(" if let Ok(pwd) = std::env::current_dir() {");
554WriteLine(" resolved_options.insert(\"ProjectDirectory\".to_string(), Value::String(pwd.to_string_lossy().to_string()));");
555WriteLine(" }");
556WriteLine(" }");
557WriteLine(" let mut args: HashMap<String, Value> = HashMap::new();");
558WriteLine(" args.insert(\"options\".to_string(), serde_json::to_value(resolved_options).unwrap_or(Value::Null));");
559WriteLine(" let result = client.invoke_capability(\"Aspire.Hosting/createBuilderWithOptions\", args)?;");
560WriteLine(" let handle: Handle = serde_json::from_value(result)?;");
561WriteLine($" Ok({builderStructName}::new(handle, client))");
562WriteLine("}");
563WriteLine();