Compare commits

...

3 Commits

Author SHA1 Message Date
Edward Shen a5c55115cf
Add nursery lint 2023-07-28 00:25:43 -07:00
Edward Shen 569758bee5
Split print code into separate functions 2023-07-28 00:25:04 -07:00
Edward Shen 537225dff2
inline format args 2023-07-28 00:17:59 -07:00
1 changed files with 57 additions and 46 deletions

View File

@ -1,4 +1,4 @@
#![warn(clippy::pedantic, clippy::cargo)] #![warn(clippy::pedantic, clippy::cargo, clippy::nursery)]
use std::collections::{BTreeMap, HashMap, HashSet}; use std::collections::{BTreeMap, HashMap, HashSet};
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
@ -83,8 +83,8 @@ enum OutputFormat {
impl Display for OutputFormat { impl Display for OutputFormat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self { match self {
OutputFormat::Table => Display::fmt("table", f), Self::Table => Display::fmt("table", f),
OutputFormat::Json => Display::fmt("json", f), Self::Json => Display::fmt("json", f),
} }
} }
} }
@ -100,9 +100,9 @@ enum Color {
impl Display for Color { impl Display for Color {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self { match self {
Color::Auto => Display::fmt("auto", f), Self::Auto => Display::fmt("auto", f),
Color::Never => Display::fmt("never", f), Self::Never => Display::fmt("never", f),
Color::Always => Display::fmt("always", f), Self::Always => Display::fmt("always", f),
} }
} }
} }
@ -343,18 +343,6 @@ async fn handle_list(conf: Config, args: List) -> Result<()> {
result: Vec<DnsResponse>, result: Vec<DnsResponse>,
} }
#[derive(Serialize, Deserialize, Debug, Tabled)]
#[tabled(rename_all = "PascalCase")]
struct DnsResponse {
name: String,
#[tabled(rename = "Type")]
r#type: RecordType,
#[tabled(rename = "IP Address")]
content: IpAddr,
proxied: bool,
id: String,
}
let mut entries = vec![]; let mut entries = vec![];
for page_no in 1.. { for page_no in 1.. {
// This technically requests one more than optimal, but tbh it // This technically requests one more than optimal, but tbh it
@ -394,39 +382,62 @@ async fn handle_list(conf: Config, args: List) -> Result<()> {
.into_iter() .into_iter()
.map(|(human, zone)| (zone.id, human)) .map(|(human, zone)| (zone.id, human))
.collect(); .collect();
match args.output { match args.output {
OutputFormat::Table => { OutputFormat::Table => print_table(&human_readable_mapping, output),
for (zone_id, data) in output { OutputFormat::Json => print_json(&human_readable_mapping, output),
println!(
"{} ({zone_id})\n{}",
human_readable_mapping.get(&zone_id).unwrap(),
Table::new(data).with(Modify::new(Column::from(0)).with(Alignment::right()))
);
}
}
OutputFormat::Json => {
let map: serde_json::Map<String, serde_json::Value> = output
.into_iter()
.map(|(zone_id, data)| {
(
human_readable_mapping.get(&zone_id).unwrap().clone(),
json!({
"id": zone_id,
"records": data,
}),
)
})
.collect();
println!(
"{}",
serde_json::to_string(&map).expect("serialization to work")
);
}
} }
Ok(()) Ok(())
} }
#[derive(Serialize, Deserialize, Debug, Tabled)]
#[tabled(rename_all = "PascalCase")]
struct DnsResponse {
name: String,
#[tabled(rename = "Type")]
r#type: RecordType,
#[tabled(rename = "IP Address")]
content: IpAddr,
proxied: bool,
id: String,
}
fn print_table(
human_readable_mapping: &HashMap<String, String>,
output: BTreeMap<String, Vec<DnsResponse>>,
) {
for (zone_id, data) in output {
println!(
"{} ({zone_id})\n{}",
human_readable_mapping.get(&zone_id).unwrap(),
Table::new(data).with(Modify::new(Column::from(0)).with(Alignment::right()))
);
}
}
fn print_json(
human_readable_mapping: &HashMap<String, String>,
output: BTreeMap<String, Vec<DnsResponse>>,
) {
let map: serde_json::Map<String, serde_json::Value> = output
.into_iter()
.map(|(zone_id, data)| {
(
human_readable_mapping.get(&zone_id).unwrap().clone(),
json!({
"id": zone_id,
"records": data,
}),
)
})
.collect();
println!(
"{}",
serde_json::to_string(&map).expect("serialization to work")
);
}
async fn get_ipv4(url: Url) -> Result<Ipv4Addr> { async fn get_ipv4(url: Url) -> Result<Ipv4Addr> {
reqwest::get(url) reqwest::get(url)
.await .await
@ -511,7 +522,7 @@ fn load_config_from_path<P: AsRef<Path>>(path: P) -> Option<Config> {
let current_mode = metadata.permissions().mode() & 0o777; let current_mode = metadata.permissions().mode() & 0o777;
if current_mode != 0o600 { if current_mode != 0o600 {
warn!( warn!(
found = format!("{:o}", current_mode), found = format!("{current_mode:o}"),
expected = "600", expected = "600",
"File permissions too broad! Your GLOBAL Cloudflare API key is accessible to all users on the system!" "File permissions too broad! Your GLOBAL Cloudflare API key is accessible to all users on the system!"
); );