1use chrono::{Datelike, Local, Timelike};
2use ipnet::IpNet;
3use std::collections::BTreeSet;
4use std::fs;
5use std::fs::OpenOptions;
6use std::io::Write;
7use std::path::Path;
8
9pub fn write_ip_lists_to_files(
12 country_code: &str,
13 ipv4_list: &BTreeSet<IpNet>,
14 ipv6_list: &BTreeSet<IpNet>,
15 mode: &str,
17) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
18 let ipv4_file = format!("IPv4_{}.txt", country_code);
19 let ipv6_file = format!("IPv6_{}.txt", country_code);
20
21 write_single_ip_list(&ipv4_file, ipv4_list, mode)?;
23 write_single_ip_list(&ipv6_file, ipv6_list, mode)?;
24
25 Ok(())
26}
27
28fn write_single_ip_list<P: AsRef<Path>>(
31 path: P,
32 nets: &BTreeSet<IpNet>,
33 mode: &str,
34) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
35 let now = Local::now();
36 let formatted_header = format!(
37 "# {}年{}月{}日 {}時{}分\n",
38 now.year(),
39 now.month(),
40 now.day(),
41 now.hour(),
42 now.minute()
43 );
44
45 let lines: Vec<String> = nets.iter().map(|net| net.to_string()).collect();
46 let content = format!("{}{}", formatted_header, lines.join("\n"));
47
48 match mode {
49 "append" => {
50 let mut file = OpenOptions::new().create(true).append(true).open(&path)?;
53 file.write_all(content.as_bytes())?;
54 println!("[output] Appended IP list to: {}", path.as_ref().display());
55 }
56 _ => {
57 fs::write(&path, &content)?;
59 println!(
60 "[output] Wrote (overwrite) IP list to: {}",
61 path.as_ref().display()
62 );
63 }
64 }
65
66 Ok(())
67}