Untitled

mail@pastecode.io avatar
unknown
rust
a year ago
3.0 kB
3
Indexable
Never
use std::fs::File;
use std::io::{BufReader, Write};
use std::path::Path;
use serde_json::Value;


fn fix_points(points: &mut Vec<(f64, f64)>) {
    let mut s = 0.0;
    for i in 0..points.len() {
        let (px, py) = points[i];
        let (qx, qy) = points[(i + 1) % points.len()];
        s += (qx - px) * (qy + py);
    }
    if s < 0.0 {
        points.reverse();
    }
}


fn main() {
    let args: Vec<String> = std::env::args().collect();

    if args.len() < 2 {
        eprintln!("Usage: {} <input_file> [--output <output_file>]", args[0]);
        std::process::exit(1);
    }

    let in_name = &args[1];
    let out_name = match args.get(2) {
        Some(arg) if arg == "--output" => {
            if args.len() < 4 {
                eprintln!("No output file provided.");
                std::process::exit(1);
            }
            args[3].clone()
        }
        _ => Path::new(in_name).with_extension("txt").to_string_lossy().to_string(),
    };

    let in_file = File::open(in_name).expect("Failed to open input file.");
    let reader = BufReader::new(in_file);
    let j: Value = serde_json::from_reader(reader).expect("Failed to parse JSON.");

    let mut out_file = File::create(&out_name).expect("Failed to create output file.");

    if let Some(layers) = j["layers"].as_array() {
        for l in layers {
            if let Some(name) = l["name"].as_str() {
                if name == "walls" {
                    if let Some(objects) = l["objects"].as_array() {
                        for o in objects {
                            if let (Some(x), Some(y), Some(polygon)) = (o["x"].as_f64(), o["y"].as_f64(), o["polygon"].as_array()) {
                                let mut points = Vec::new();
                                for p in polygon {
                                    if let (Some(px), Some(py)) = (p["x"].as_f64(), p["y"].as_f64()) {
                                        points.push((x + px, y + py));
                                    }
                                }
                                fix_points(&mut points);
                                let s = points.iter().map(|(x, y)| format!("({} {})", x, y)).collect::<Vec<_>>().join(" ");
                                out_file.write_all(format!("wall [{}]\n", s).as_bytes()).expect("Failed to write to output file.");
                            }
                        }
                    }
                } else if name == "objects" {
                    if let Some(objects) = l["objects"].as_array() {
                        for o in objects {
                            if let (Some(name), Some(x), Some(y)) = (o["name"].as_str(), o["x"].as_f64(), o["y"].as_f64()) {
                                out_file.write_all(format!("{} ({} {})\n", name, x, y).as_bytes()).expect("Failed to write to output file.");
                            }
                        }
                    }
                }
            }
        }
    }
}