Compare commits

..

No commits in common. "a5c55115cf585880bae6cc9dcc62e7c55a2a8f72" and "87001a98500b37c6d10c558a6251d6b6ba8d60ed" have entirely different histories.

View file

@ -1,4 +1,4 @@
#![warn(clippy::pedantic, clippy::cargo, clippy::nursery)]
#![warn(clippy::pedantic, clippy::cargo)]
use std::collections::{BTreeMap, HashMap, HashSet};
use std::fmt::{Debug, Display};
@ -83,8 +83,8 @@ enum OutputFormat {
impl Display for OutputFormat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Table => Display::fmt("table", f),
Self::Json => Display::fmt("json", f),
OutputFormat::Table => Display::fmt("table", f),
OutputFormat::Json => Display::fmt("json", f),
}
}
}
@ -100,9 +100,9 @@ enum Color {
impl Display for Color {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Auto => Display::fmt("auto", f),
Self::Never => Display::fmt("never", f),
Self::Always => Display::fmt("always", f),
Color::Auto => Display::fmt("auto", f),
Color::Never => Display::fmt("never", f),
Color::Always => Display::fmt("always", f),
}
}
}
@ -343,6 +343,18 @@ async fn handle_list(conf: Config, args: List) -> Result<()> {
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![];
for page_no in 1.. {
// This technically requests one more than optimal, but tbh it
@ -382,62 +394,39 @@ async fn handle_list(conf: Config, args: List) -> Result<()> {
.into_iter()
.map(|(human, zone)| (zone.id, human))
.collect();
match args.output {
OutputFormat::Table => print_table(&human_readable_mapping, output),
OutputFormat::Json => print_json(&human_readable_mapping, output),
OutputFormat::Table => {
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()))
);
}
}
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(())
}
#[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> {
reqwest::get(url)
.await
@ -522,7 +511,7 @@ fn load_config_from_path<P: AsRef<Path>>(path: P) -> Option<Config> {
let current_mode = metadata.permissions().mode() & 0o777;
if current_mode != 0o600 {
warn!(
found = format!("{current_mode:o}"),
found = format!("{:o}", current_mode),
expected = "600",
"File permissions too broad! Your GLOBAL Cloudflare API key is accessible to all users on the system!"
);