h3o_cli/commands/
grid_disk.rs1use anyhow::{Context, Result as AnyResult};
4use clap::{Parser, ValueEnum};
5use h3o::CellIndex;
6use serde::Serialize;
7
8#[derive(Parser, Debug)]
13pub struct Args {
14 #[arg(short, long)]
16 origin: Option<CellIndex>,
17
18 #[arg(short, long)]
20 radius: u32,
21
22 #[arg(short, long, default_value_t = false)]
24 distance: bool,
25
26 #[arg(short, long, value_enum, default_value_t = Format::Text)]
28 format: Format,
29
30 #[arg(short, long, default_value_t = false)]
32 pretty: bool,
33}
34
35#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
36enum Format {
37 Text,
38 Json,
39}
40
41pub fn run(args: &Args) -> AnyResult<()> {
43 let indexes = crate::utils::get_cell_indexes(args.origin);
44
45 match args.format {
46 Format::Text => disks_to_text(indexes, args.radius, args.distance),
47 Format::Json => {
48 disks_to_json(indexes, args.radius, args.distance, args.pretty)
49 }
50 }
51 .context("gridDisk")?;
52
53 Ok(())
54}
55
56fn disks_to_text(
58 indexes: impl IntoIterator<Item = AnyResult<CellIndex>>,
59 radius: u32,
60 with_distance: bool,
61) -> AnyResult<()> {
62 let disks = indexes
63 .into_iter()
64 .map(|input| input.map(|index| index.grid_disk_distances_safe(radius)));
65
66 if with_distance {
67 for disk in disks {
68 let disk = disk?;
69 for (index, distance) in disk {
70 println!("{index} {distance}");
71 }
72 }
73 } else {
74 for disk in disks {
75 let disk = disk?;
76 for (index, _) in disk {
77 println!("{index}");
78 }
79 }
80 }
81
82 Ok(())
83}
84
85fn disks_to_json(
87 indexes: impl IntoIterator<Item = AnyResult<CellIndex>>,
88 radius: u32,
89 with_distance: bool,
90 pretty: bool,
91) -> AnyResult<()> {
92 let disks = indexes.into_iter().map(|input| {
93 input.map(|origin| {
94 origin
95 .grid_disk_distances_safe(radius)
96 .map(|(index, distance)| {
97 (crate::json::CellIndex::from(index), distance)
98 })
99 })
100 });
101
102 if with_distance {
103 #[derive(Serialize)]
104 struct Neighbor {
105 index: crate::json::CellIndex,
106 distance: u32,
107 }
108 let disks = disks
109 .map(|result| {
110 result.map(|disk| {
111 disk.map(|(index, distance)| Neighbor { index, distance })
112 .collect::<Vec<_>>()
113 })
114 })
115 .collect::<AnyResult<Vec<_>>>()?;
116 crate::json::print(&disks, pretty)
117 } else {
118 let disks = disks
119 .map(|result| {
120 result.map(|disk| {
121 disk.map(|(index, _)| index).collect::<Vec<_>>()
122 })
123 })
124 .collect::<AnyResult<Vec<_>>>()?;
125 crate::json::print(&disks, pretty)
126 }
127}