use ; use ; use ; use ; use ; use ; use ; pub PathBuf build(bool force) { var start = time::Instant::now(); var root = env::current_dir().expect("Unable to find project root"); PathBuf src = root.join("src"); PathBuf out = root.join(".mist/src"); build_dir(&root, &src, &src, &out, force); var elapsed = start.elapsed(); println!( "\x1b[32m\nTranspile successful\x1b[0m in \x1b[34m{:.2?}\x1b[0m", elapsed ); root } void build_dir(Path* root, Path* base_src, Path* current, Path* out, bool force) { var entries = match (fs::read_dir(current)) { Ok[entries] => entries; Err[e] => { eprintln!( "error: failed to read directory {}\n {}", current.display(), e ); process::exit(1); } }; for (entry : entries) { var entry = match (entry) { Ok[entry] => entry; Err[e] => { eprintln!("error: failed to read directory entry\n {}", e); process::exit(1); } }; PathBuf path = entry.path(); if (path.is_dir()) { build_dir(root, base_src, &path, out, force); continue; } Path* relative = path.strip_prefix(base_src).expect("Failed to strip base src from path"); if (path.extension().and_then(|var e| e.to_str()) != Some("mist")) { PathBuf dest = out.join(relative); Option parent = dest.parent(); if (parent.is_some()) { fs::create_dir_all(parent.unwrap()).expect("failed to create output directory"); } if (!force && should_skip(&path, &dest)) { continue } fs::copy(&path, dest).expect("Failed to copy non-mist file"); continue; } PathBuf output_file = out.join(relative).with_extension("rs"); if (!force && should_skip(&path, &output_file)) { continue; } Option parent = output_file.parent(); if (parent.is_some()) { fs::create_dir_all(parent.unwrap()).expect("failed to create output directory"); } String source = match (fs::read_to_string(&path)) { Ok[s] => s; Err[e] => { eprintln!("error: failed to read file {}\n {}", path.display(), e); process::exit(1); } }; var mut gc = mist_codegen::RustCodegen::new(); String output = gc.generate(match (mist_parser::parse(&source)) { Ok[ast] => ast; Err[e] => { match (e) { error::ParseError::Ast[e] => { var start_pos = e.span.start_pos().line_col(); var span = e.span.as_str(); eprintln!( "\n{}:{}:{}\n \x1b[31mError\x1b[0m: {}\n\t{}{}\t{}", path.as_os_str().display(), start_pos.0, start_pos.1, e.error_message, span, if span.ends_with("\n") { "" } else { "\n" }, "^".repeat(span.trim().len()), ); process::exit(1); } error::ParseError::PreAst[e] => { eprintln!("error: parse failed in {}\n{}", path.display(), e); process::exit(1); } } } }); var res = fs::write(&output_file, output); if (res.is_err()) { eprintln!( "error: failed to write output {}\n {}", output_file.display(), res.unwrap_err(), ); process::exit(1); } } } bool should_skip(Path* source, Path* output) { var src_time = fs::metadata(source) .ok() .and_then(|var v| v.modified().ok()); var out_time = fs::metadata(output) .ok() .and_then(|var v| v.modified().ok()); out_time .map(|var out_time| out_time >= src_time.unwrap()) .unwrap_or_default() }