///|
pub fn help() -> String {
"MoonWeave: plain | twill | satin [grid|json|svg|report]\nJSON input: json [grid|json|svg|report]\nGrid input: grid [grid|json|svg|report]"
}
///|
pub(all) struct Analysis {
width : Int
height : Int
shafts : Int
repeat_size : RepeatSize
front : Array[PeriodicFloat]
back : Array[PeriodicFloat]
bindings : BindingCounts
} derive(Eq, Debug, ToJson, FromJson)
///|
pub fn Draft::analyze(self : Draft) -> Analysis {
{
width: self.width(),
height: self.height(),
shafts: self.shafts,
repeat_size: self.repeat_size(),
front: self.periodic_floats(2).unwrap(),
back: self.periodic_floats(2, back=true).unwrap(),
bindings: self.bindings(periodic=true),
}
}
///|
/// Pure command dispatcher: args excludes program name; never opens files or runs processes.
pub fn command(args : Array[String]) -> Result[String, String] {
if args == [] || args == ["help"] || args == ["--help"] {
return Ok(help())
}
let name = args[0]
let input_mode = name == "json" || name == "grid"
let count = if input_mode { 2 } else { 3 }
if args.length() != count && args.length() != count + 1 {
return Err("cli.arguments")
}
let format = if args.length() == count + 1 { args[count] } else { "grid" }
let built = if input_mode {
if name == "json" {
read_json(args[1])
} else {
read_grid(args[1])
}
} else {
try {
let a = @string.parse_int(args[1])
let b = @string.parse_int(args[2])
match name {
"plain" => plain(a, b)
"twill" => twill(a, b)
"satin" => satin(a, b)
_ => Err("cli.command")
}
} catch {
_ => Err("cli.integer")
}
}
match built {
Err(e) => Err(e)
Ok(d) =>
match format {
"grid" => Ok(d.write_grid())
"json" => Ok(d.write_json())
"svg" => d.svg()
"report" => Ok(d.analyze().to_json().stringify())
_ => Err("cli.format")
}
}
}