///|
fn main {
let args = @env.args()
let file_args = args.filter(fn(a) {
!(a.contains(".wasm") || a.contains(".moon\\bin"))
})
if file_args.length() == 0 {
println("usage: moon run cmd/main -- ")
return
}
let path = file_args[0]
let content = @fs.read_file_to_string(path) catch {
@fs.IOError(msg) => {
println("error: failed to read '\{path}': \{msg}")
return
}
}
let top = parse_top()
let line_count = count_lines(content)
println("=== \{path} ===")
let start = @env.now()
match @nestedtext.loads(content, top) {
Ok(Some(value)) => {
let elapsed = @env.now() - start
let out_path = path + ".out"
let output = @nestedtext.dumps(value, @nestedtext.DumpOptions::default())
@fs.write_string_to_file(out_path, output) catch {
@fs.IOError(msg) =>
println("error: failed to write '\{out_path}': \{msg}")
}
println("PASS | \{line_count} lines | \{elapsed}ms | -> \{out_path}")
}
Ok(None) => {
let elapsed = @env.now() - start
println("PASS | empty | \{elapsed}ms")
}
Err(e) => {
let elapsed = @env.now() - start
let top_label = top_label(top)
println("FAIL | \{line_count} lines | \{elapsed}ms | Top::\{top_label}")
print_error_ctx(content, e)
}
}
}
///|
fn print_error_ctx(content : String, e : @nestedtext.NestedTextError) -> Unit {
match e.lineno {
Some(lineno) => {
println("")
let line = get_line(content, lineno)
println(" \{e.to_string()}")
if line != "" {
println(" \{lineno} | \{line}")
}
match e.colno {
Some(colno) => {
let indicator = spaces(colno) + "^"
println(" \{indicator}")
}
None => ()
}
}
None => println(" \{e.to_string()}")
}
println("")
}
///|
fn get_line(content : String, lineno : Int32) -> String {
let lines = content.split("\n").to_array()
for i, view in lines {
if i + 1 == lineno {
return view.to_owned()
}
}
""
}
///|
fn spaces(n : Int32) -> String {
let buf = StringBuilder()
for _ in 0.. Int32 {
content.split("\n").count()
}
///|
fn parse_top() -> @nestedtext.Top {
match @env.get_env_var("NESTEDTEXT_TOP") {
Some("dict") => @nestedtext.Top::Dict
Some("list") => @nestedtext.Top::List
Some("string") => @nestedtext.Top::String
_ => @nestedtext.Top::Any
}
}
///|
fn top_label(top : @nestedtext.Top) -> String {
match top {
@nestedtext.Top::Dict => "Dict"
@nestedtext.Top::List => "List"
@nestedtext.Top::String => "String"
@nestedtext.Top::Any => "Any"
}
}