Files
misses/misses-compiler/src/main.rs
T
Claude 3be88ec21f Add misses init command with binary and library scaffold modes
`misses init [--lib] [dir]` scaffolds a new proc-macro crate that uses
misses as its build toolchain. Two modes are supported:

Binary mode (default):
  The .mrs source files live in src/macros/ and are compiled to
  $OUT_DIR at build time via a generated build.rs. The generated
  Rust code is never committed — users must have misses installed
  to build from source.

Library mode (--lib):
  The generated code is committed to generated/ so downstream users
  of the crate need no misses install at all. The .mrs source and
  build.rs are still present for the library author, who can
  regenerate via `cargo build --features misses-source`. The
  misses-source feature makes misses an optional build-dependency
  and gates the regeneration path in build.rs with #[cfg(feature)].

The command also teaches `main.rs` a proper subcommand dispatch so
that `misses <file.mrs>` (compile) and `misses init` are cleanly
separated.

https://claude.ai/code/session_01D2g6zGJsBeUEzxBb7AvFDt
2026-03-08 09:30:14 +00:00

70 lines
2.1 KiB
Rust

mod init;
use std::path::PathBuf;
fn main() {
let args: Vec<String> = std::env::args().collect();
match args.get(1).map(String::as_str) {
Some("init") => {
let is_lib = args.iter().any(|a| a == "--lib");
let dir = args
.iter()
.skip(2)
.find(|a| !a.starts_with('-'))
.map(String::as_str)
.unwrap_or(".");
init::run(dir, is_lib);
}
Some(_) => compile(&args),
None => {
print_usage();
std::process::exit(1);
}
}
}
fn compile(args: &[String]) {
let input_path = PathBuf::from(&args[1]);
let src = match std::fs::read_to_string(&input_path) {
Ok(s) => s,
Err(e) => {
eprintln!("error reading {}: {}", input_path.display(), e);
std::process::exit(1);
}
};
let ast = match misses::parse(&src) {
Ok(a) => a,
Err(e) => {
eprintln!("parse error: {}", e);
std::process::exit(1);
}
};
let generated = misses::codegen(&ast);
if args.len() >= 3 {
let output_path = PathBuf::from(&args[2]);
if let Err(e) = std::fs::write(&output_path, &generated) {
eprintln!("error writing {}: {}", output_path.display(), e);
std::process::exit(1);
}
} else {
print!("{}", generated);
}
}
fn print_usage() {
eprintln!("Usage:");
eprintln!(" misses <input.mrs> [output.rs] Compile a .mrs file to Rust");
eprintln!(" misses init [--lib] [dir] Scaffold a new misses project");
eprintln!();
eprintln!("Modes for `misses init`:");
eprintln!(" (default) Binary — .mrs sources are compiled at build time via build.rs;");
eprintln!(" generated code lives in \\$OUT_DIR and is never committed.");
eprintln!(" --lib Library — generated code is committed to generated/ so");
eprintln!(" downstream users need no misses install. Rebuild with");
eprintln!(" `cargo build --features misses-source`.");
}