windjammer 0.48.0

A simple language inspired by Go, Ruby, and Elixir that transpiles to Rust - 80% of Rust's power with 20% of the complexity
Documentation
// CLI Tool Example - File processor with concurrency
use std::fs
use std::path::Path
use clap::Parser
use std::sync::mpsc

@command(
    name: "wj-process",
    about: "Process text files concurrently",
    version: "1.0"
)
@derive(Clone)
struct Args {
    @arg(help: "Input files to process")
    files: Vec<string>,
    
    @arg(short: 'o', long: "output", help: "Output directory")
    output_dir: Option<string>,
    
    @arg(short: 'w', long: "workers", default_value: "4", help: "Number of worker threads")
    workers: int,
    
    @arg(short: 'v', long: "verbose", help: "Verbose output")
    verbose: bool,
    
    @arg(long: "uppercase", help: "Convert to uppercase")
    uppercase: bool,
    
    @arg(long: "reverse", help: "Reverse lines")
    reverse: bool,
}

struct ProcessResult {
    input_file: string,
    output_file: string,
    lines_processed: int,
}

fn process_file(path: string, args: &Args) -> Result<ProcessResult, string> {
    if args.verbose {
        println("Processing: {}", path)
    }
    
    // Read the file
    let content = fs.read_to_string(&path)?
    let mut lines: Vec<string> = content.lines().map(|l| l).collect()
    
    // Apply transformations
    if args.uppercase {
        lines = lines.iter().map(|l| l.to_uppercase()).collect()
    }
    
    if args.reverse {
        lines.reverse()
    }
    
    let processed = lines.join("\n")
    
    // Determine output path
    let output_path = match &args.output_dir {
        Some(dir) => {
            let filename = Path::new(&path).file_name().unwrap()
            format!("{}/{}", dir, filename.to_string_lossy())
        }
        None => {
            format!("{}.processed", path)
        }
    }
    
    // Write output
    fs.write(&output_path, processed)?
    
    Ok(ProcessResult {
        input_file: path,
        output_file: output_path,
        lines_processed: lines.len() as int,
    })
}

fn main() -> Result<(), string> {
    let args = Args.parse()
    
    // Create output directory if needed
    match &args.output_dir {
        Some(dir) => fs.create_dir_all(dir)?,
        None => ()
    }
    
    if args.verbose {
        println("Processing {} files with {} workers", args.files.len(), args.workers)
    }
    
    // Process files concurrently using channels
    let (tx, rx) = mpsc::channel()
    
    let file_count = args.files.len()
    let files = args.files.clone()
    
    // Spawn worker threads
    for file in files {
        let tx_clone = tx.clone()
        let args_copy = args.clone()
        
        thread {
            let result = process_file(file, &args_copy)
            tx_clone.send(result).unwrap()
        }
    }
    
    // Drop the original sender so the channel closes when done
    drop(tx)
    
    // Collect results
    let mut total_lines = 0
    let mut success_count = 0
    let mut error_count = 0
    
    for result in rx {
        match result {
            Ok(res) => {
                success_count += 1
                total_lines += res.lines_processed
                
                if args.verbose {
                    println("✓ {} -> {} ({} lines)", 
                        res.input_file, 
                        res.output_file, 
                        res.lines_processed)
                }
            }
            Err(e) => {
                error_count += 1
                eprintln("✗ Error: {}", e)
            }
        }
    }
    
    // Print summary
    println("\nSummary:")
    println("  Files processed: {}/{}", success_count, file_count)
    println("  Total lines: {}", total_lines)
    
    if error_count > 0 {
        println("  Errors: {}", error_count)
    }
    
    Ok(())
}