use std::env; use std::process::Command; fn main() { let args: Vec = env::args().skip(1).collect(); match args.first().map(String::as_str) { Some("test") => run_cargo("test", &[]), Some("build-ios") => { let script = project_root().join("scripts/build-ios.sh"); let status = Command::new("bash") .arg(script) .status() .expect("failed to run build-ios.sh"); std::process::exit(status.code().unwrap_or(1)); } Some("fixtures") => { println!("fixtures/"); println!(" markdown/sample.md — all block types"); println!(" markdown/large_markdown.md — 200-heading stress test"); println!(" text/sample.txt — multi-paragraph plain text"); println!(" text/large_text.txt — 500-line stress test"); println!(" images/test-red.png — 1×1 red pixel PNG"); println!(" pdf/text_pdf.pdf — minimal 2-page PDF"); println!(" pdf/scanned_pdf.pdf — minimal 1-page PDF"); println!(" epub/simple.epub — 1-chapter EPUB"); println!(" epub/epub_with_toc.epub — 3-chapter EPUB with NCX TOC"); println!(" invalid_file.bin — 1KB random bytes"); } Some("verify-ios") => { let root = project_root(); let xcframework = root.join("bindings/ios/ZxDocumentRuntime.xcframework"); if !xcframework.exists() { eprintln!("ERROR: XCFramework not found at {}", xcframework.display()); std::process::exit(1); } let binding = root.join("bindings/ios/generated/zx_document.swift"); if !binding.exists() { eprintln!("ERROR: Swift binding not found at {}", binding.display()); std::process::exit(1); } let header = root.join("bindings/ios/generated/zx_documentFFI.h"); if !header.exists() { eprintln!("ERROR: header not found at {}", header.display()); std::process::exit(1); } println!("✅ XCFramework: {}", xcframework.display()); println!("✅ Swift binding: {}", binding.display()); println!("✅ Header: {}", header.display()); println!("✅ verify-ios passed"); } _ => { println!("zhixi-document-runtime xtask"); println!(); println!("Commands:"); println!(" test Run all Rust tests"); println!(" build-ios Build iOS XCFramework + Swift bindings"); println!(" verify-ios Verify XCFramework/binding/header exist"); println!(" fixtures List available fixture files"); } } } fn project_root() -> std::path::PathBuf { let manifest_dir = env!("CARGO_MANIFEST_DIR"); std::path::Path::new(manifest_dir).parent().unwrap().parent().unwrap().to_path_buf() } fn run_cargo(cmd: &str, args: &[&str]) { let mut child = Command::new("cargo") .arg(cmd) .args(args) .current_dir(project_root()) .spawn() .expect("failed to start cargo"); let status = child.wait().expect("failed to wait on cargo"); std::process::exit(status.code().unwrap_or(1)); }