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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use anyhow::{Context, Result as AnyResult};
use clap::{Parser, ValueEnum};
use h3o::CellIndex;
use serde::Serialize;
#[derive(Parser, Debug)]
pub struct Args {
#[arg(short, long)]
origin: Option<CellIndex>,
#[arg(short, long)]
radius: u32,
#[arg(short, long, default_value_t = false)]
distance: bool,
#[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.origin);
match args.format {
Format::Text => disks_to_text(indexes, args.radius, args.distance),
Format::Json => {
disks_to_json(indexes, args.radius, args.distance, args.pretty)
}
}
.context("gridDisk")?;
Ok(())
}
fn disks_to_text(
indexes: impl IntoIterator<Item = AnyResult<CellIndex>>,
radius: u32,
with_distance: bool,
) -> AnyResult<()> {
let disks = indexes
.into_iter()
.map(|input| input.map(|index| index.grid_disk_distances_safe(radius)));
if with_distance {
for disk in disks {
let disk = disk?;
for (index, distance) in disk {
println!("{index} {distance}");
}
}
} else {
for disk in disks {
let disk = disk?;
for (index, _) in disk {
println!("{index}");
}
}
}
Ok(())
}
fn disks_to_json(
indexes: impl IntoIterator<Item = AnyResult<CellIndex>>,
radius: u32,
with_distance: bool,
pretty: bool,
) -> AnyResult<()> {
let disks = indexes.into_iter().map(|input| {
input.map(|origin| {
origin
.grid_disk_distances_safe(radius)
.map(|(index, distance)| {
(crate::json::CellIndex::from(index), distance)
})
})
});
if with_distance {
#[derive(Serialize)]
struct Neighbor {
index: crate::json::CellIndex,
distance: u32,
}
let disks = disks
.map(|result| {
result.map(|disk| {
disk.map(|(index, distance)| Neighbor { index, distance })
.collect::<Vec<_>>()
})
})
.collect::<AnyResult<Vec<_>>>()?;
crate::json::print(&disks, pretty)
} else {
let disks = disks
.map(|result| {
result.map(|disk| {
disk.map(|(index, _)| index).collect::<Vec<_>>()
})
})
.collect::<AnyResult<Vec<_>>>()?;
crate::json::print(&disks, pretty)
}
}