#[cfg(feature = "net")]
use std::net::IpAddr;
#[cfg(feature = "net")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "net")]
use sysinfo::Networks;
#[derive(Debug, Serialize, Deserialize)]
#[cfg(feature = "net")]
pub struct IpAddress {
pub interface: String,
pub ip: IpAddr,
pub prefix: u8,
}
#[derive(Debug, Serialize, Deserialize)]
#[cfg(feature = "net")]
pub struct IpV4Address {
pub interface: String,
pub octets: [u8; 4],
pub prefix: u8,
}
#[cfg(feature = "net")]
pub fn list_ip_address() -> Vec<IpAddress> {
let networks = Networks::new_with_refreshed_list();
let mut address = Vec::new();
for (name, network) in networks.iter() {
for ip in network.ip_networks() {
address.push(IpAddress {
interface: name.clone(),
ip: ip.addr,
prefix: ip.prefix,
});
}
}
address
}
#[cfg(feature = "net")]
pub fn list_ipv4() -> Vec<IpV4Address> {
let networks = Networks::new_with_refreshed_list();
let mut address = Vec::new();
for (name, network) in networks.iter() {
for ip in network.ip_networks() {
if let IpAddr::V4(addr) = ip.addr {
address.push(IpV4Address {
interface: name.clone(),
prefix: ip.prefix,
octets: addr.octets(),
});
}
}
}
address
}
#[cfg(feature = "net")]
pub fn block_download_file(
url: &str,
save_path: &str,
callback: Option<fn(cur: u64, total: u64)>,
) -> Result<(), String> {
use reqwest::{blocking::Client, header::CONTENT_LENGTH};
use std::{
fs::File,
io::{Read, Write},
path::Path,
sync::OnceLock,
};
static CLIENT: OnceLock<Client> = OnceLock::new();
let client = CLIENT.get_or_init(Client::new);
let response = client.head(url).send().map_err(|e| e.to_string())?;
let total_size = if let Some(size) = response.headers().get(CONTENT_LENGTH) {
size.to_str()
.map_err(|e| e.to_string())?
.parse::<u64>()
.unwrap_or(0)
} else {
0
};
let mut response = client.get(url).send().map_err(|e| e.to_string())?; let mut file = File::create(Path::new(save_path)).map_err(|e| e.to_string())?;
let mut downloaded: u64 = 0;
let mut buffer = [0; 8192]; while let Ok(n) = response.read(&mut buffer) {
if n == 0 {
break;
}
file.write_all(&buffer[..n]).map_err(|e| e.to_string())?;
downloaded += n as u64;
if let Some(callback) = callback {
callback(downloaded, total_size);
}
}
Ok(())
}
#[cfg(feature = "net")]
pub async fn download_file(
url: &str,
save_path: &str,
callback: Option<fn(cur: u64, total: u64)>,
) -> Result<(), String> {
use reqwest::{header::CONTENT_LENGTH, Client};
use std::{fs::File, io::Write, path::Path, sync::OnceLock};
static CLIENT: OnceLock<Client> = OnceLock::new();
let client = CLIENT.get_or_init(Client::new);
let response = client.head(url).send().await.map_err(|e| e.to_string())?;
let total_size = if let Some(size) = response.headers().get(CONTENT_LENGTH) {
size.to_str()
.map_err(|e| e.to_string())?
.parse::<u64>()
.unwrap_or(0)
} else {
0
};
let mut response = client.get(url).send().await.map_err(|e| e.to_string())?; let mut file = File::create(Path::new(save_path)).map_err(|e| e.to_string())?;
let mut downloaded: u64 = 0;
while let Some(bytes) = response.chunk().await.map_err(|e| e.to_string())? {
file.write_all(&bytes).map_err(|e| e.to_string())?;
downloaded += bytes.len() as u64;
if let Some(callback) = callback {
callback(downloaded, total_size);
}
}
Ok(())
}
#[cfg(feature = "net")]
pub fn block_download_string(url: &str) -> Result<String, String> {
use reqwest::blocking::Client;
use std::sync::OnceLock;
static CLIENT: OnceLock<Client> = OnceLock::new();
let client = CLIENT.get_or_init(Client::new);
let response = client.get(url).send().map_err(|e| e.to_string())?; let data = response.bytes().map_err(|e| e.to_string())?;
let data = String::from_utf8(data.to_vec()).map_err(|e| e.to_string())?;
Ok(data)
}
#[cfg(feature = "net")]
pub async fn download_string(url: &str) -> Result<String, String> {
use reqwest::Client;
use std::sync::OnceLock;
static CLIENT: OnceLock<Client> = OnceLock::new();
let client = CLIENT.get_or_init(Client::new);
let response = client.get(url).send().await.map_err(|e| e.to_string())?; let data = response.bytes().await.map_err(|e| e.to_string())?;
let data = String::from_utf8(data.to_vec()).map_err(|e| e.to_string())?;
Ok(data)
}
#[cfg(feature = "net")]
pub fn block_download_json<T>(url: &str) -> Result<T, String>
where
T: serde::de::DeserializeOwned,
{
use reqwest::blocking::Client;
use std::sync::OnceLock;
static CLIENT: OnceLock<Client> = OnceLock::new();
let client = CLIENT.get_or_init(Client::new);
let response = client.get(url).send().map_err(|e| e.to_string())?; let data: T = response.json().map_err(|e| e.to_string())?;
Ok(data)
}
#[cfg(feature = "net")]
pub async fn download_json<T>(url: &str) -> Result<T, String>
where
T: serde::de::DeserializeOwned,
{
use std::sync::OnceLock;
use reqwest::Client;
static CLIENT: OnceLock<Client> = OnceLock::new();
let client = CLIENT.get_or_init(Client::new);
let response = client.get(url).send().await.map_err(|e| e.to_string())?; let data: T = response.json().await.map_err(|e| e.to_string())?;
Ok(data)
}
#[cfg(feature = "net")]
pub fn block_post_json<T>(url: &str, data: T) -> Result<reqwest::blocking::Response, reqwest::Error>
where
T: serde::Serialize,
{
use std::sync::OnceLock;
use reqwest::blocking::Client;
static CLIENT: OnceLock<Client> = OnceLock::new();
let client = CLIENT.get_or_init(Client::new);
let resp = client.post(url).json(&data).send()?;
Ok(resp)
}
#[cfg(feature = "net")]
pub async fn post_json<T>(url: &str, data: T) -> Result<reqwest::Response, reqwest::Error>
where
T: serde::Serialize,
{
use std::sync::OnceLock;
use reqwest::Client;
static CLIENT: OnceLock<Client> = OnceLock::new();
let client = CLIENT.get_or_init(Client::new);
let resp = client.post(url).json(&data).send().await?;
Ok(resp)
}
#[test]
#[cfg(feature = "net")]
fn test_list_ip_address() {
let ret = list_ip_address();
println!("{:#?}", ret);
}