rename ecstore

This commit is contained in:
weisd
2024-06-25 15:45:21 +08:00
parent 7634eea4a2
commit 0a9f06096b
19 changed files with 2844 additions and 57 deletions
+2
View File
@@ -0,0 +1,2 @@
pub mod net;
pub mod string;
+94
View File
@@ -0,0 +1,94 @@
use std::{
collections::HashMap,
net::{IpAddr, ToSocketAddrs},
};
use anyhow::Error;
use netif;
use url::Host;
pub fn split_host_port(s: &str) -> Result<(String, u16), Error> {
let parts: Vec<&str> = s.split(':').collect();
if parts.len() == 2 {
if let Ok(port) = parts[1].parse::<u16>() {
return Ok((parts[0].to_string(), port));
}
}
Err(Error::msg("Invalid address format or port number"))
}
// is_local_host 判断是否是本地ip
pub fn is_local_host(host: Host<&str>, port: u16, local_port: u16) -> bool {
let local_ips = must_get_local_ips();
let local_map =
local_ips
.iter()
.map(|ip| ip.to_string())
.fold(HashMap::new(), |mut acc, item| {
*acc.entry(item).or_insert(true) = true;
acc
});
let is_local_host = match host {
Host::Domain(domain) => {
let ips: Vec<String> = (domain, 0)
.to_socket_addrs()
.unwrap_or(Vec::new().into_iter())
.map(|addr| addr.ip().to_string())
.collect();
let mut isok = false;
for ip in ips.iter() {
if local_map.contains_key(ip) {
isok = true;
break;
}
}
isok
}
Host::Ipv4(ip) => local_map.contains_key(&ip.to_string()),
Host::Ipv6(ip) => local_map.contains_key(&ip.to_string()),
};
if port > 0 {
return is_local_host && port == local_port;
}
is_local_host
}
pub fn must_get_local_ips() -> Vec<IpAddr> {
let mut v: Vec<IpAddr> = Vec::new();
if let Some(up) = netif::up().ok() {
v = up.map(|x| x.address().to_owned()).collect();
}
v
}
#[cfg(test)]
mod test {
use std::net::Ipv4Addr;
use super::*;
#[test]
fn test_must_get_local_ips() {
let ips = must_get_local_ips();
for ip in ips.iter() {
println!("{:?}", ip)
}
}
#[test]
fn test_is_local_host() {
// let host = Host::Ipv4(Ipv4Addr::new(192, 168, 0, 233));
let host = Host::Ipv4(Ipv4Addr::new(127, 0, 0, 1));
// let host = Host::Domain("localhost");
let port = 0;
let local_port = 9000;
let is = is_local_host(host, port, local_port);
assert!(is)
}
}
+133
View File
@@ -0,0 +1,133 @@
use std::collections::HashMap;
use std::fmt;
#[derive(Debug, Clone)]
pub struct StringSet(HashMap<String, ()>);
impl StringSet {
// ToSlice - returns StringSet as a vector of strings.
pub fn to_slice(&self) -> Vec<String> {
let mut keys = self.0.keys().cloned().collect::<Vec<String>>();
keys.sort();
keys
}
// IsEmpty - returns whether the set is empty or not.
pub fn is_empty(&self) -> bool {
self.0.len() == 0
}
// Add - adds a string to the set.
pub fn add(&mut self, s: String) {
self.0.insert(s, ());
}
// Remove - removes a string from the set. It does nothing if the string does not exist in the set.
pub fn remove(&mut self, s: &str) {
self.0.remove(s);
}
// Contains - checks if a string is in the set.
pub fn contains(&self, s: &str) -> bool {
self.0.contains_key(s)
}
// FuncMatch - returns a new set containing each value that passes the match function.
pub fn func_match<F>(&self, match_fn: F, match_string: &str) -> StringSet
where
F: Fn(&str, &str) -> bool,
{
StringSet(
self.0
.iter()
.filter(|(k, _)| match_fn(k, match_string))
.map(|(k, _)| (k.clone(), ()))
.collect::<HashMap<String, ()>>(),
)
}
// ApplyFunc - returns a new set containing each value processed by 'apply_fn'.
pub fn apply_func<F>(&self, apply_fn: F) -> StringSet
where
F: Fn(&str) -> String,
{
StringSet(
self.0
.iter()
.map(|(k, _)| (apply_fn(k), ()))
.collect::<HashMap<String, ()>>(),
)
}
// Equals - checks whether the given set is equal to the current set or not.
pub fn equals(&self, other: &StringSet) -> bool {
if self.0.len() != other.0.len() {
return false;
}
self.0.iter().all(|(k, _)| other.0.contains_key(k))
}
// Intersection - returns the intersection with the given set as a new set.
pub fn intersection(&self, other: &StringSet) -> StringSet {
StringSet(
self.0
.iter()
.filter(|(k, _)| other.0.contains_key::<String>(k))
.map(|(k, _)| (k.clone(), ()))
.collect::<HashMap<String, ()>>(),
)
}
// Difference - returns the difference with the given set as a new set.
pub fn difference(&self, other: &StringSet) -> StringSet {
StringSet(
self.0
.iter()
.filter(|(k, _)| !other.0.contains_key::<String>(k))
.map(|(k, _)| (k.clone(), ()))
.collect::<HashMap<String, ()>>(),
)
}
// Union - returns the union with the given set as a new set.
pub fn union(&self, other: &StringSet) -> StringSet {
let mut new_set = self.clone();
for (k, _) in other.0.iter() {
new_set.0.insert(k.clone(), ());
}
new_set
}
}
// Implementing JSON serialization and deserialization would require the serde crate.
// You would also need to implement Display and PartialEq traits for more idiomatic Rust.
// Implementing Display trait to provide a string representation of the set.
impl fmt::Display for StringSet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.to_slice().join(", "))
}
}
// Implementing PartialEq and Eq traits to allow comparison of StringSet instances.
impl PartialEq for StringSet {
fn eq(&self, other: &StringSet) -> bool {
self.equals(other)
}
}
impl Eq for StringSet {}
// NewStringSet - creates a new string set.
pub fn new_string_set() -> StringSet {
StringSet(HashMap::new())
}
// CreateStringSet - creates a new string set with given string values.
pub fn create_string_set(sl: Vec<String>) -> StringSet {
let mut set = new_string_set();
for k in sl {
set.add(k);
}
set
}