use crate::errors::Result;
use std::path::Path;
#[derive(Debug, Clone)]
pub struct UserInfo {
pub name: String,
pub email: String,
pub avatar: Option<String>,
}
#[derive(Debug, Clone)]
pub struct BridgeType {
pub name: String,
pub fields: Vec<BridgeField>,
}
#[derive(Debug, Clone)]
pub struct BridgeField {
pub name: String,
pub ty: String,
}
pub trait TypeBridge {
fn bridge_info() -> BridgeType;
}
pub struct NargoBridge {
types: Vec<BridgeType>,
}
impl NargoBridge {
pub fn new() -> Self {
Self { types: Vec::new() }
}
pub fn register<T: TypeBridge>(&mut self) {
self.types.push(T::bridge_info());
}
pub fn generate(&self, output_path: &Path) -> Result<()> {
let mut ts_code = String::new();
ts_code.push_str("// Generated by nargo-bridge. DO NOT EDIT.\n\n");
for ty in &self.types {
ts_code.push_str(&format!("export interface {} {{\n", ty.name));
for field in &ty.fields {
let ts_type = self.map_to_ts(&field.ty);
ts_code.push_str(&format!(" {}: {};\n", field.name, ts_type));
}
ts_code.push_str("}\n\n");
}
if let Some(parent) = output_path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(output_path, ts_code)?;
Ok(())
}
fn map_to_ts(&self, rust_type: &str) -> String {
match rust_type {
"String" | "&str" => "string".to_string(),
"u8" | "u16" | "u32" | "u64" | "i8" | "i16" | "i32" | "i64" | "f32" | "f64"
| "usize" => "number".to_string(),
"bool" => "boolean".to_string(),
_ if rust_type.starts_with("Vec<") => {
let inner = &rust_type[4..rust_type.len() - 1];
format!("{}[]", self.map_to_ts(inner))
}
_ if rust_type.starts_with("Option<") => {
let inner = &rust_type[7..rust_type.len() - 1];
format!("{} | null", self.map_to_ts(inner))
}
_ => rust_type.to_string(),
}
}
}
impl Default for NargoBridge {
fn default() -> Self {
Self::new()
}
}