[go: up one dir, main page]

Menu

[a969d6]: / src / args.rs  Maximize  Restore  History

Download this file

108 lines (89 with data), 3.1 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
use clap::{ArgGroup, Parser};
use colored::Colorize;
use std::path::Path;
use std::process::exit;
use std::time::Duration;
/// Command-line arguments parser
#[derive(Parser, Debug)]
#[command(author, version, about)]
#[command(group(
ArgGroup::new("location")
.required(true)
.args(&["bbox", "file"])
))]
pub struct Args {
/// Bounding box of the area (min_lng,min_lat,max_lng,max_lat) (required)
#[arg(long, allow_hyphen_values = true)]
pub bbox: Option<String>,
/// JSON file containing OSM data (optional)
#[arg(long)]
pub file: Option<String>,
/// Path to the Minecraft world (required)
#[arg(long, required = true)]
pub path: String,
/// Downloader method (requests/curl/wget) (optional)
#[arg(long, default_value = "requests")]
pub downloader: String,
/// World scale to use, in blocks per meter
#[arg(long, default_value = "1.0")]
pub scale: f64,
/// Ground level to use in the Minecraft world
#[arg(long, default_value_t = -62)]
pub ground_level: i32,
/// Enable winter mode (default: false)
#[arg(long, default_value_t = false)]
pub winter: bool,
/// Enable terrain (optional)
#[arg(long, default_value_t = false, action = clap::ArgAction::SetFalse)]
pub terrain: bool,
/// Enable debug mode (optional)
#[arg(long, default_value_t = false, action = clap::ArgAction::SetTrue)]
pub debug: bool,
/// Set floodfill timeout (seconds) (optional)
#[arg(long, value_parser = parse_duration)]
pub timeout: Option<Duration>,
}
impl Args {
pub fn run(&self) {
// Validating the world path
let mc_world_path: &Path = Path::new(&self.path);
if !mc_world_path.join("region").exists() {
eprintln!(
"{}",
"Error! No Minecraft world found at the given path"
.red()
.bold()
);
exit(1);
}
// Validating bbox if provided
if let Some(bbox) = &self.bbox {
if !validate_bounding_box(bbox) {
eprintln!("{}", "Error! Invalid bbox input".red().bold());
exit(1);
}
}
}
}
/// Validates the bounding box string
fn validate_bounding_box(bbox: &str) -> bool {
let parts: Vec<&str> = bbox.split(',').collect();
if parts.len() != 4 {
return false;
}
let min_lng: f64 = parts[0].parse().ok().unwrap_or(0.0);
let min_lat: f64 = parts[1].parse().ok().unwrap_or(0.0);
let max_lng: f64 = parts[2].parse().ok().unwrap_or(0.0);
let max_lat: f64 = parts[3].parse().ok().unwrap_or(0.0);
if !(-180.0..=180.0).contains(&min_lng) || !(-180.0..=180.0).contains(&max_lng) {
return false;
}
if !(-90.0..=90.0).contains(&min_lat) || !(-90.0..=90.0).contains(&max_lat) {
return false;
}
min_lng < max_lng && min_lat < max_lat
}
fn parse_duration(arg: &str) -> Result<std::time::Duration, std::num::ParseIntError> {
let seconds = arg.parse()?;
Ok(std::time::Duration::from_secs(seconds))
}