cfun/
c_net.rs

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