From 6b232850ccd6b2f878be1f3b73a007dcaf689747 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Mon, 21 Apr 2025 10:25:07 -0700 Subject: [PATCH] build: add `wit_type_to_ts()` function --- src/build/caller_utils_generator.rs | 49 +++++++++++++++++++++++++++++ src/build/wit_generator.rs | 5 +-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/build/caller_utils_generator.rs b/src/build/caller_utils_generator.rs index a4ec673f..1e374508 100644 --- a/src/build/caller_utils_generator.rs +++ b/src/build/caller_utils_generator.rs @@ -184,6 +184,55 @@ fn generate_default_value(rust_type: &str) -> String { } } +fn wit_type_to_ts(wit_type: &str) -> String { + match wit_type { + // Integer types - all become "number" in TypeScript + "s8" | "u8" | "s16" | "u16" | "s32" | "u32" | "s64" | "u64" => "number".to_string(), + // Floating point types - also "number" in TypeScript + "f32" | "f64" => "number".to_string(), + // Other primitive types + "string" => "string".to_string(), + "str" => "string".to_string(), + "char" => "string".to_string(), + "bool" => "boolean".to_string(), + "_" => "void".to_string(), + "unit" => "void".to_string(), + // Special types + "address" => "Address".to_string(), + // Collection types with generics + t if t.starts_with("list<") => { + let inner_type = &t[5..t.len() - 1]; + format!("{}[]", wit_type_to_ts(inner_type)) + } + t if t.starts_with("option<") => { + let inner_type = &t[7..t.len() - 1]; + format!("{} | null", wit_type_to_ts(inner_type)) + } + t if t.starts_with("result<") => { + let inner_part = &t[7..t.len() - 1]; + if let Some(comma_pos) = inner_part.find(',') { + let ok_type = &inner_part[..comma_pos].trim(); + let err_type = &inner_part[comma_pos + 1..].trim(); + format!( + "{{ Ok: {} }} | {{ Err: {} }}", + wit_type_to_ts(ok_type), + wit_type_to_ts(err_type) + ) + } else { + format!("{{ Ok: {} }} | {{ Err: null }}", wit_type_to_ts(inner_part)) + } + } + t if t.starts_with("tuple<") => { + let inner_types = &t[6..t.len() - 1]; + let ts_types: Vec = + inner_types.split(", ").map(|t| wit_type_to_ts(t)).collect(); + format!("[{}]", ts_types.join(", ")) + } + // Custom types (assumed to be in kebab-case) need to be converted to PascalCase + _ => to_pascal_case(wit_type).to_string(), + } +} + // Structure to represent a field in a WIT signature struct struct SignatureField { name: String, diff --git a/src/build/wit_generator.rs b/src/build/wit_generator.rs index e9a832ae..d100d723 100644 --- a/src/build/wit_generator.rs +++ b/src/build/wit_generator.rs @@ -518,16 +518,16 @@ fn find_rust_projects(base_dir: &Path) -> Vec { .filter_map(Result::ok) { let path = entry.path(); - if !path.is_dir() || path == base_dir { continue; } + let cargo_toml = path.join("Cargo.toml"); println!("Checking {}", cargo_toml.display()); - if !cargo_toml.exists() { continue; } + // Try to read and parse Cargo.toml let Ok(content) = fs::read_to_string(&cargo_toml) else { continue; @@ -535,6 +535,7 @@ fn find_rust_projects(base_dir: &Path) -> Vec { let Ok(cargo_data) = content.parse::() else { continue; }; + // Check for the specific metadata let Some(metadata) = cargo_data .get("package")