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