h3o_cli/commands/
grid_path.rs

1//! Expose [`CellIndex::grid_path_cells`]
2
3use anyhow::{ensure, Context, Result as AnyResult};
4use clap::{ArgGroup, Parser, ValueEnum};
5use either::Either;
6use h3o::CellIndex;
7
8/// Compute the path between the given cell indexes.
9#[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    /// The starting point, must be paired with `-d/--destination`.
17    #[arg(short, long)]
18    source: Option<CellIndex>,
19
20    /// The destination point, must be paired with `-s/--source`.
21    #[arg(short, long)]
22    destination: Option<CellIndex>,
23
24    /// Output format.
25    #[arg(short, long, value_enum, default_value_t = Format::Text)]
26    format: Format,
27
28    /// Prettify the output (JSON only).
29    #[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
39/// Run the `gridPath` command.
40pub 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}