nargo-types 0.0.1

Nargo common types and error handling
Documentation
//! Bridge module for generating TypeScript types from Rust structs.

use crate::errors::Result;
use std::path::Path;

/// User information for bridge.
#[derive(Debug, Clone)]
pub struct UserInfo {
    /// User name.
    pub name: String,
    /// User email.
    pub email: String,
    /// User avatar URL.
    pub avatar: Option<String>,
}

/// Bridge type information.
#[derive(Debug, Clone)]
pub struct BridgeType {
    /// Type name.
    pub name: String,
    /// Type fields.
    pub fields: Vec<BridgeField>,
}

/// Bridge field information.
#[derive(Debug, Clone)]
pub struct BridgeField {
    /// Field name.
    pub name: String,
    /// Field type.
    pub ty: String,
}

/// Trait for type bridging.
pub trait TypeBridge {
    /// Returns bridge type information.
    fn bridge_info() -> BridgeType;
}

/// Bridge for generating TypeScript types.
pub struct NargoBridge {
    types: Vec<BridgeType>,
}

impl NargoBridge {
    /// Create a new bridge instance.
    pub fn new() -> Self {
        Self { types: Vec::new() }
    }

    /// Register a type for bridging.
    pub fn register<T: TypeBridge>(&mut self) {
        self.types.push(T::bridge_info());
    }

    /// Generate TypeScript types to the output path.
    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()
    }
}