h3o_cli/commands/
resolution_info.rs1use anyhow::Result as AnyResult;
4use clap::{Parser, ValueEnum};
5use h3o::Resolution;
6use serde::Serialize;
7use std::fmt;
8
9#[derive(Parser, Debug)]
11pub struct Args {
12 #[arg(short, long)]
14 resolution: Option<Resolution>,
15
16 #[arg(short, long, value_enum, default_value_t = Format::Text)]
18 format: Format,
19
20 #[arg(short, long, default_value_t = false)]
22 pretty: bool,
23}
24
25#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum)]
26enum Format {
27 Text,
28 Json,
29}
30
31pub fn run(args: &Args) -> AnyResult<()> {
33 if let Some(resolution) = args.resolution {
34 let info = ResolutionInfo::from(resolution);
35 match args.format {
36 Format::Text => println!("{info}"),
37 Format::Json => crate::json::print(&info, args.pretty)?,
38 }
39 return Ok(());
40 }
41
42 match args.format {
43 Format::Text => {
44 println!("╔═{c:═>10}═╦═{c:═>15}═╦═{c:═>20}═╦═{c:═>14}═╗", c = '═');
45 println!(
46 "║ {:<10} ║ {:<15} ║ {:<20} ║ {:<14} ║",
47 "Resolution", "Cell count", "Hexagon area", "Edge length"
48 );
49 println!("╠═{c:═>10}═╬═{c:═>15}═╬═{c:═>20}═╬═{c:═>14}═╣", c = '═');
50 for resolution in
51 Resolution::range(Resolution::Zero, Resolution::Fifteen)
52 {
53 let info = ResolutionInfo::from(resolution);
54 let (area, area_unit, length, length_unit) = if info.resolution
55 < Resolution::Eight
56 {
57 (info.hexagon_area_km2, "km2", info.edge_length_km, "km")
58 } else {
59 (
60 info.hexagon_area_km2 * 1e6,
61 "m2",
62 info.edge_length_km * 1e3,
63 "m",
64 )
65 };
66 println!(
67 "║ {:>10} ║ {:>15} ║ {:16.3} {:<3} ║ {:11.3} {:<2} ║",
68 u8::from(info.resolution),
69 info.cell_count,
70 area,
71 area_unit,
72 length,
73 length_unit
74 );
75 }
76 println!("╚═{c:═>10}═╩═{c:═>15}═╩═{c:═>20}═╩═{c:═>14}═╝", c = '═');
77 }
78 Format::Json => {
79 let infos =
80 Resolution::range(Resolution::Zero, Resolution::Fifteen)
81 .map(Into::into)
82 .collect::<Vec<ResolutionInfo>>();
83 crate::json::print(&infos, args.pretty)?;
84 }
85 }
86
87 Ok(())
88}
89
90#[derive(Serialize)]
93struct ResolutionInfo {
94 resolution: Resolution,
95 cell_count: u64,
96 hexagon_area_km2: f64,
97 edge_length_km: f64,
98}
99
100impl From<Resolution> for ResolutionInfo {
101 fn from(value: Resolution) -> Self {
102 Self {
103 resolution: value,
104 cell_count: value.cell_count(),
105 hexagon_area_km2: value.area_km2(),
106 edge_length_km: value.edge_length_km(),
107 }
108 }
109}
110
111impl fmt::Display for ResolutionInfo {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 writeln!(f, "resolution: {}", self.resolution)?;
114 writeln!(f, "cell count: {}", self.cell_count)?;
115 if self.resolution < Resolution::Eight {
116 writeln!(f, "hexagon area: {} km2", self.hexagon_area_km2)?;
117 write!(f, "edge length: {} km", self.edge_length_km)
118 } else {
119 writeln!(f, "hexagon area: {} m2", self.hexagon_area_km2 * 1e6)?;
120 write!(f, "edge length: {} m", self.edge_length_km * 1e3)
121 }
122 }
123}