cfun/
c_net.rs

1#[cfg(feature = "net")]
2use std::net::IpAddr;
3
4#[cfg(feature = "net")]
5use serde::{Deserialize, Serialize};
6#[cfg(feature = "net")]
7use sysinfo::Networks;
8#[derive(Debug, Serialize, Deserialize)]
9#[cfg(feature = "net")]
10pub struct IpAddress {
11    pub interface: String,
12    pub ip: IpAddr,
13    pub prefix: u8,
14}
15
16#[derive(Debug, Serialize, Deserialize)]
17#[cfg(feature = "net")]
18pub struct IpV4Address {
19    pub interface: String,
20    pub octets: [u8; 4],
21    pub prefix: u8,
22}
23
24/// get all ip address
25#[cfg(feature = "net")]
26pub fn list_ip_address() -> Vec<IpAddress> {
27    let networks = Networks::new_with_refreshed_list();
28    let mut address = Vec::new();
29    for (name, network) in networks.iter() {
30        for ip in network.ip_networks() {
31            address.push(IpAddress {
32                interface: name.clone(),
33                ip: ip.addr,
34                prefix: ip.prefix,
35            });
36        }
37    }
38    address
39}
40
41/// get all ipv4 address
42#[cfg(feature = "net")]
43pub fn list_ipv4() -> Vec<IpV4Address> {
44    let networks = Networks::new_with_refreshed_list();
45    let mut address = Vec::new();
46    for (name, network) in networks.iter() {
47        for ip in network.ip_networks() {
48            if let IpAddr::V4(addr) = ip.addr {
49                address.push(IpV4Address {
50                    interface: name.clone(),
51                    prefix: ip.prefix,
52                    octets: addr.octets(),
53                });
54            }
55        }
56    }
57    address
58}
59
60/// send get request save to file
61#[cfg(feature = "net")]
62pub fn block_download_file(
63    url: &str,
64    save_path: &str,
65    callback: Option<fn(cur: u64, total: u64)>,
66) -> Result<(), String> {
67    use reqwest::{blocking::Client, header::CONTENT_LENGTH};
68    use std::{
69        fs::File,
70        io::{Read, Write},
71        path::Path,
72    };
73    let client = Client::new();
74    let response = client.head(url).send().map_err(|e| e.to_string())?; // 先获取文件大小
75
76    let total_size = if let Some(size) = response.headers().get(CONTENT_LENGTH) {
77        size.to_str()
78            .map_err(|e| e.to_string())?
79            .parse::<u64>()
80            .unwrap_or(0)
81    } else {
82        0
83    };
84
85    let mut response = client.get(url).send().map_err(|e| e.to_string())?; // 开始下载
86    let mut file = File::create(Path::new(save_path)).map_err(|e| e.to_string())?;
87
88    let mut downloaded: u64 = 0;
89    let mut buffer = [0; 8192]; // 8KB 缓冲区
90    while let Ok(n) = response.read(&mut buffer) {
91        if n == 0 {
92            break;
93        }
94        file.write_all(&buffer[..n]).map_err(|e| e.to_string())?;
95        downloaded += n as u64;
96        if let Some(callback) = callback {
97            callback(downloaded, total_size);
98        }
99    }
100    Ok(())
101}
102
103/// send get request save to file
104#[cfg(feature = "net")]
105pub async fn download_file(
106    url: &str,
107    save_path: &str,
108    callback: Option<fn(cur: u64, total: u64)>,
109) -> Result<(), String> {
110    use reqwest::{header::CONTENT_LENGTH, Client};
111    use std::{fs::File, io::Write, path::Path};
112    let client = Client::new();
113    let response = client.head(url).send().await.map_err(|e| e.to_string())?; // 先获取文件大小
114
115    let total_size = if let Some(size) = response.headers().get(CONTENT_LENGTH) {
116        size.to_str()
117            .map_err(|e| e.to_string())?
118            .parse::<u64>()
119            .unwrap_or(0)
120    } else {
121        0
122    };
123
124    let mut response = client.get(url).send().await.map_err(|e| e.to_string())?; // 开始下载
125    let mut file = File::create(Path::new(save_path)).map_err(|e| e.to_string())?;
126
127    let mut downloaded: u64 = 0;
128
129    while let Some(bytes) = response.chunk().await.map_err(|e| e.to_string())? {
130        file.write_all(&bytes).map_err(|e| e.to_string())?;
131        downloaded += bytes.len() as u64;
132        if let Some(callback) = callback {
133            callback(downloaded, total_size);
134        }
135    }
136    Ok(())
137}
138
139/// send get request to get content as string
140#[cfg(feature = "net")]
141pub fn block_download_string(url: &str) -> Result<String, String> {
142    use reqwest::blocking::Client;
143    let client = Client::new();
144    let response = client.get(url).send().map_err(|e| e.to_string())?; // 开始下载
145    let data = response.bytes().map_err(|e| e.to_string())?;
146    let data = String::from_utf8(data.to_vec()).map_err(|e| e.to_string())?;
147    Ok(data)
148}
149
150/// send get request to get content as string
151#[cfg(feature = "net")]
152pub async fn download_string(url: &str) -> Result<String, String> {
153    use reqwest::Client;
154    let client = Client::new();
155    let response = client.get(url).send().await.map_err(|e| e.to_string())?; // 开始下载
156    let data = response.bytes().await.map_err(|e| e.to_string())?;
157    let data = String::from_utf8(data.to_vec()).map_err(|e| e.to_string())?;
158    Ok(data)
159}
160
161/// send get request to get content as json
162#[cfg(feature = "net")]
163pub fn block_download_json<T>(url: &str) -> Result<T, String>
164where
165    T: serde::de::DeserializeOwned,
166{
167    use reqwest::blocking::Client;
168    let client = Client::new();
169    let response = client.get(url).send().map_err(|e| e.to_string())?; // 开始下载
170    let data: T = response.json().map_err(|e| e.to_string())?;
171    Ok(data)
172}
173
174/// send get request to get content as json
175#[cfg(feature = "net")]
176pub async fn download_json<T>(url: &str) -> Result<T, String>
177where
178    T: serde::de::DeserializeOwned,
179{
180    use reqwest::Client;
181    let client = Client::new();
182    let response = client.get(url).send().await.map_err(|e| e.to_string())?; // 开始下载
183    let data: T = response.json().await.map_err(|e| e.to_string())?;
184    Ok(data)
185}
186
187#[test]
188#[cfg(feature = "net")]
189fn test_list_ip_address() {
190    let ret = list_ip_address();
191    println!("{:#?}", ret);
192}