h3o_cli/commands/
grid_path.rs1use anyhow::{Context, Result as AnyResult, ensure};
4use clap::{ArgGroup, Parser, ValueEnum};
5use either::Either;
6use h3o::CellIndex;
7
8#[derive(Parser, Debug)]
10#[command(group(ArgGroup::new("ll")
11 .args(["source", "destination"])
12 .multiple(true)
13 .requires_all(["source", "destination"]))
14)]
15pub struct Args {
16 #[arg(short, long)]
18 source: Option<CellIndex>,
19
20 #[arg(short, long)]
22 destination: Option<CellIndex>,
23
24 #[arg(short, long, value_enum, default_value_t = Format::Text)]
26 format: Format,
27
28 #[arg(short, long, default_value_t = false)]
30 pretty: bool,
31}
32
33#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
34enum Format {
35 Text,
36 Json,
37}
38
39pub fn run(args: &Args) -> AnyResult<()> {
41 let indexes =
42 if let (Some(src), Some(dst)) = (args.source, args.destination) {
43 vec![src, dst]
44 } else {
45 crate::io::read_cell_indexes().collect::<AnyResult<Vec<_>>>()?
46 };
47 ensure!(indexes.len() >= 2, "not enough cell indexes");
48
49 let mut path = indexes
50 .windows(2)
51 .flat_map(|segment| match segment[0].grid_path_cells(segment[1]) {
52 Ok(iter) => Either::Right(iter),
53 Err(err) => Either::Left(std::iter::once(Err(err))),
54 })
55 .collect::<Result<Vec<_>, _>>()
56 .context("compute paths")?;
57 path.dedup();
58
59 match args.format {
60 Format::Text => {
61 for index in path {
62 println!("{index}");
63 }
64 }
65 Format::Json => {
66 let path = path
67 .into_iter()
68 .map(Into::into)
69 .collect::<Vec<crate::json::CellIndex>>();
70 crate::json::print(&path, args.pretty)?;
71 }
72 }
73
74 Ok(())
75}