lucky-point 0.1.0

A cross-platform CLI tool to recommend lucky ports based on system usage.
Documentation
use std::net::{TcpListener, UdpSocket};
use rand::Rng;

pub fn is_port_occupied(port: u16) -> bool {
  let a =match TcpListener::bind(format!("0.0.0.0:{}", port)) {
      Ok(_) => false,
      Err(_) => true,
  };
  let b = match UdpSocket::bind(format!("0.0.0.0:{}", port)) {
      Ok(_) => false,
      Err(_) => true,
  };
  a || b
}

pub fn scan_occupied_ports() -> Vec<u16> {
  let mut occupied = Vec::new();
  for port in 1024..=65535 {
      if is_port_occupied(port) {
          occupied.push(port);
      }
  }
  occupied
}


pub fn is_lucky(port: u16) -> bool {
  let port_str = port.to_string();
  port_str.contains('6') || port_str.contains('8') && !port_str.contains('4')
}


pub fn find_lucky_ports(count: usize) -> Vec<u16> {
  let mut rng = rand::rng();
  let occupied = scan_occupied_ports();
  let mut lucky_ports = Vec::new();

  while lucky_ports.len() < count {
      let candidate = rng.random_range(1024..=65535);
      if !occupied.contains(&candidate) && is_lucky(candidate) {
          lucky_ports.push(candidate);
      }
  }

  lucky_ports
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_is_lucky() {
        assert!(is_lucky(68));  // 包含 6 和 8
        assert!(is_lucky(8888));  // 包含多个 8
        assert!(!is_lucky(44));  // 包含 4,不吉利
        assert!(!is_lucky(123));  // 不包含 6 或 8
    }

    #[test]
    fn test_is_port_occupied() {
        // 这是一个简单的测试,可能需要模拟,因为实际端口占用会变化
        // 假设某些常用端口(如 80)通常被占用
        assert!(is_port_occupied(80));  // 假设 80 端口被占用(HTTP)
        assert!(!is_port_occupied(54321));  // 假设高位端口通常空闲
    }
}