iotas 0.1.0

Iota Syntaxis 1.0 RC5 parser — the Unicode variant of Jot Syntax (https://iotasyntaxis.org)
Documentation
use std::io::Read;
use std::path::PathBuf;
use std::process::ExitCode;

const USAGE: &str = "Usage: iotas [OPTIONS] [FILE]

Iota Syntaxis parser (the Unicode variant of Jot Syntax). Reads from
FILE or stdin, emits parsed metadata as JSON.

Options:
  --version          Print version and exit
  --no-loc           Omit `loc` and `raw` from emitted construct objects
  -h, --help         Show this help
";

fn main() -> ExitCode {
    let args: Vec<String> = std::env::args().skip(1).collect();
    let mut files: Vec<PathBuf> = Vec::new();
    let mut no_loc = false;
    for arg in args {
        match arg.as_str() {
            "--version" => {
                println!("iotas {}", iotas::VERSION);
                return ExitCode::SUCCESS;
            }
            "--help" | "-h" => {
                print!("{}", USAGE);
                return ExitCode::SUCCESS;
            }
            "--no-loc" => no_loc = true,
            s if s.starts_with('-') => {
                eprintln!("Error: unknown option '{}'", s);
                return ExitCode::FAILURE;
            }
            _ => files.push(PathBuf::from(arg)),
        }
    }

    let mut cfg = iotas::load();
    if no_loc {
        cfg.set_bool("emit_loc", false);
    }

    let text = match files.first() {
        Some(path) => match std::fs::read_to_string(path) {
            Ok(t) => t,
            Err(e) => {
                eprintln!("Error: cannot open '{}': {}", path.display(), e);
                return ExitCode::FAILURE;
            }
        },
        None => {
            let mut buf = String::new();
            if let Err(e) = std::io::stdin().read_to_string(&mut buf) {
                eprintln!("Error reading stdin: {}", e);
                return ExitCode::FAILURE;
            }
            buf
        }
    };

    let result = iotas::parse(&text, &cfg);
    match serde_json::to_string_pretty(&result) {
        Ok(s) => {
            println!("{}", s);
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Error encoding JSON: {}", e);
            ExitCode::FAILURE
        }
    }
}