///|
#cfg(target="native")
extern "C" fn exit(code : Int32) = "exit"
///|
#cfg(target="wasm")
fn exit(code : UInt32) = "wasi_snapshot_preview1" "proc_exit"
///|
async fn[T] die(message : String) -> T {
@stdio.stderr.write("\{message}\n") catch {
_ => ()
}
exit(1)
panic()
}
///|
async fn write_stdout(message : String) -> Unit {
try @stdio.stdout.write(message) catch {
err => die("error: failed to write stdout: \{err}")
} noraise {
_ => ()
}
}
///|
fn program_args() -> ArrayView[String] {
let args = @env.args()
if args.length() > 1 {
args[1:]
} else {
[]
}
}
///|
async fn read_file(path : String) -> String {
try @fs.read_file(path).text() catch {
err => {
die("error: failed to read \{path}: \{err}")
""
}
} noraise {
source => source
}
}
///|
async fn read_stdin() -> String {
try @stdio.stdin.read_all().text() catch {
err => {
die("error: failed to read stdin: \{err}")
""
}
} noraise {
source => source
}
}
///|
async fn write_result(output : String?, content : String) -> Unit {
let content = "\{content}\n"
match output {
Some(path) =>
try @fs.write_file(path, content, create_mode=CreateOrTruncate) catch {
err => die("error: failed to write \{path}: \{err}")
} noraise {
_ => ()
}
None => write_stdout(content)
}
}
///|
async fn run_legacy(options : LegacyOptions) -> Unit {
let kind = match kind_from_options(options) {
Some(kind) => kind
None => {
die("error: --file-type pkg|mod|work is required for stdin or -c input")
"pkg"
}
}
let source = match options.source {
File(path) => read_file(path)
Stdin => read_stdin()
Code(source) => source
}
let ast = parse_config(kind, source)
write_result(options.output, ToJson::to_json(ast).stringify())
}
///|
async fn main {
match parse_cli(program_args()) {
Help(text) => write_stdout("\{text}\n")
Error(message) => die(message)
RunLegacy(options) => run_legacy(options)
}
}