1use crate::common::{IpFamily, OutputFormat};
2use crate::output_common::{make_header, write_list_nft, write_list_txt};
3use chrono::Local;
4use ipnet::IpNet;
5use std::{collections::BTreeSet, error::Error};
6
7pub fn write_ip_lists_to_files(
9 country_code: &str,
10 ipv4_list: &BTreeSet<IpNet>,
11 ipv6_list: &BTreeSet<IpNet>,
12 mode: &str,
13 format_enum: OutputFormat,
14) -> Result<(), Box<dyn Error + Send + Sync>> {
15 match format_enum {
16 OutputFormat::Txt => {
17 let now_str = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
18 let ipv4_file = format!("IPv4_{}.txt", country_code);
20 let header_v4 = make_header(&now_str, country_code, "N/A");
21 write_list_txt(&ipv4_file, ipv4_list, mode, &header_v4)?;
22
23 let ipv6_file = format!("IPv6_{}.txt", country_code);
25 let header_v6 = make_header(&now_str, country_code, "N/A");
26 write_list_txt(&ipv6_file, ipv6_list, mode, &header_v6)?;
27 }
28 OutputFormat::Nft => {
29 let now_str = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
30 let ipv4_file = format!("IPv4_{}.nft", country_code);
32 let header_v4 = make_header(&now_str, country_code, "N/A");
33 write_list_nft(&ipv4_file, ipv4_list, mode, &header_v4)?;
34
35 let ipv6_file = format!("IPv6_{}.nft", country_code);
37 let header_v6 = make_header(&now_str, country_code, "N/A");
38 write_list_nft(&ipv6_file, ipv6_list, mode, &header_v6)?;
39 }
40 }
41 Ok(())
42}
43
44pub fn write_as_ip_list_to_file(
46 as_number: &str,
47 family: IpFamily,
48 ipnets: &BTreeSet<IpNet>,
49 mode: &str,
50 format_enum: OutputFormat,
51) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
52 let now_str = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
53 let header = make_header(&now_str, "N/A", as_number);
54
55 match format_enum {
56 OutputFormat::Txt => {
57 let file_name = format!("AS_{}_{}.txt", as_number, family.as_str());
58 write_list_txt(&file_name, ipnets, mode, &header)?;
59 println!(
60 "[output] Wrote/append TXT for AS_{} {}",
61 as_number,
62 family.as_str()
63 );
64 }
65 OutputFormat::Nft => {
66 let file_name = format!("AS_{}_{}.nft", as_number, family.as_str());
67 write_list_nft(&file_name, ipnets, mode, &header)?;
68 println!(
69 "[output] Wrote/append NFT for AS_{} {}",
70 as_number,
71 family.as_str()
72 );
73 }
74 }
75 Ok(())
76}
77
78pub fn write_overlap_to_file(
80 country_code: &str,
81 as_number: &str,
82 overlaps: &BTreeSet<IpNet>,
83 mode: &str,
84 format_enum: OutputFormat,
85) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
86 let overlaps_v4: BTreeSet<IpNet> = overlaps
88 .iter()
89 .cloned()
90 .filter(|net| matches!(net, IpNet::V4(_)))
91 .collect();
92
93 let overlaps_v6: BTreeSet<IpNet> = overlaps
94 .iter()
95 .cloned()
96 .filter(|net| matches!(net, IpNet::V6(_)))
97 .collect();
98
99 if overlaps_v4.is_empty() && overlaps_v6.is_empty() {
100 println!(
101 "[overlap] No overlap found for country={} and AS={}",
102 country_code, as_number
103 );
104 return Ok(());
105 }
106
107 match format_enum {
110 OutputFormat::Txt => {
111 if !overlaps_v4.is_empty() {
113 let filename_v4 = format!("overlap_{}_{}_IPv4.txt", country_code, as_number);
114 let now_str = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
115 let header_v4 = make_header(&now_str, country_code, as_number);
116 write_list_txt(&filename_v4, &overlaps_v4, mode, &header_v4)?;
117 println!("[overlap] Wrote/append IPv4 overlaps to: {}", filename_v4);
118 }
119 if !overlaps_v6.is_empty() {
121 let filename_v6 = format!("overlap_{}_{}_IPv6.txt", country_code, as_number);
122 let now_str = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
123 let header_v6 = make_header(&now_str, country_code, as_number);
124 write_list_txt(&filename_v6, &overlaps_v6, mode, &header_v6)?;
125 println!("[overlap] Wrote/append IPv6 overlaps to: {}", filename_v6);
126 }
127 }
128 OutputFormat::Nft => {
129 if !overlaps_v4.is_empty() {
131 let filename_v4 = format!("overlap_{}_{}_IPv4.nft", country_code, as_number);
132 let now_str = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
133 let header_v4 = make_header(&now_str, country_code, as_number);
134 write_list_nft(&filename_v4, &overlaps_v4, mode, &header_v4)?;
135 println!(
136 "[overlap] Wrote/append IPv4 overlaps nft to: {}",
137 filename_v4
138 );
139 }
140 if !overlaps_v6.is_empty() {
142 let filename_v6 = format!("overlap_{}_{}_IPv6.nft", country_code, as_number);
143 let now_str = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
144 let header_v6 = make_header(&now_str, country_code, as_number);
145 write_list_nft(&filename_v6, &overlaps_v6, mode, &header_v6)?;
146 println!(
147 "[overlap] Wrote/append IPv6 overlaps nft to: {}",
148 filename_v6
149 );
150 }
151 }
152 }
153
154 Ok(())
155}