fire_scope/
output_common.rs

1use ipnet::IpNet;
2use std::{collections::BTreeSet, path::Path};
3use tokio::fs::{self, OpenOptions};
4use tokio::io::AsyncWriteExt;
5
6/// 汎用ヘッダー生成: こちらは非同期要素がないのでそのまま
7pub fn make_header(now_str: &str, country_code: &str, as_number: &str) -> String {
8    format!(
9        "# Generated at: {}\n# Country Code: {}\n# AS Number: {}\n\n",
10        now_str, country_code, as_number
11    )
12}
13
14/// TXT出力用の共通ヘルパー
15pub async fn write_list_txt<P: AsRef<Path>>(
16    path: P,
17    ipnets: &BTreeSet<IpNet>,
18    mode: &str,
19    header: &str,
20) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
21    let body = ipnets
22        .iter()
23        .map(|net| net.to_string())
24        .collect::<Vec<_>>()
25        .join("\n");
26
27    let content = format!("{}{}\n", header, body);
28
29    match mode {
30        "append" => {
31            // 非同期OpenOptions
32            let mut file = OpenOptions::new()
33                .create(true)
34                .append(true)
35                .open(path)
36                .await?;
37            file.write_all(content.as_bytes()).await?;
38        }
39        _ => {
40            // まるごと書き込む場合
41            fs::write(path, &content).await?;
42        }
43    }
44
45    Ok(())
46}
47
48/// NFT 出力用の共通ヘルパー
49pub async fn write_list_nft<P: AsRef<Path>>(
50    path: P,
51    ipnets: &BTreeSet<IpNet>,
52    mode: &str,
53    header: &str,
54) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
55    let file_path = path.as_ref();
56    let define_name = file_path
57        .file_stem()
58        .and_then(|os| os.to_str())
59        .unwrap_or("unknown_define");
60
61    let mut content = String::new();
62    content.push_str(header);
63    content.push_str(&format!("define {} {{\n", define_name));
64    for net in ipnets {
65        content.push_str(&format!("    {},\n", net));
66    }
67    content.push_str("}\n");
68
69    match mode {
70        "append" => {
71            let mut file = OpenOptions::new()
72                .create(true)
73                .append(true)
74                .open(file_path)
75                .await?;
76            file.write_all(content.as_bytes()).await?;
77        }
78        _ => {
79            fs::write(file_path, &content).await?;
80        }
81    }
82
83    Ok(())
84}