use anyhow::{Context, Result as AnyResult};
use clap::{Parser, ValueEnum};
use h3o::{CellIndex, LocalIJ};
use serde::Serialize;
#[derive(Parser, Debug)]
pub struct Args {
#[arg(short, long)]
origin: CellIndex,
#[arg(short, long)]
index: Option<CellIndex>,
#[arg(short, long, value_enum, default_value_t = Format::Text)]
format: Format,
#[arg(short, long, default_value_t = false)]
pretty: bool,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
enum Format {
Text,
Json,
}
pub fn run(args: &Args) -> AnyResult<()> {
let indexes = crate::utils::get_cell_indexes(args.index);
let coords = indexes
.map(|input| input.map(|index| index.to_local_ij(args.origin).ok()));
match args.format {
Format::Text => local_ij_to_text(coords),
Format::Json => local_ij_to_json(coords, args.pretty),
}
.context("cellToLocalIj")?;
Ok(())
}
fn local_ij_to_text(
coords: impl IntoIterator<Item = AnyResult<Option<LocalIJ>>>,
) -> AnyResult<()> {
for coord in coords {
coord?.map_or_else(
|| println!("NA"),
|coord| println!("{} {}", coord.coord.i, coord.coord.j),
);
}
Ok(())
}
fn local_ij_to_json(
coords: impl IntoIterator<Item = AnyResult<Option<LocalIJ>>>,
pretty: bool,
) -> AnyResult<()> {
#[derive(Serialize)]
struct CoordIJ {
i: i32,
j: i32,
}
let coords = coords
.into_iter()
.map(|result| {
result.map(|value| {
value.map(|coord| CoordIJ {
i: coord.coord.i,
j: coord.coord.j,
})
})
})
.collect::<AnyResult<Vec<_>>>()?;
crate::json::print(&coords, pretty)
}