mod xsetroot; use chrono::prelude::*; use std::{ fmt, io::{prelude::*, BufReader}, net::Shutdown, os::unix::net::{UnixListener, UnixStream}, sync::{Arc, Mutex}, thread, time, }; use xsetroot::XSetRoot; type MTState = Arc>; fn handle_client(stream: UnixStream, st: MTState) { let mut rdr = BufReader::new(&stream); let mut msg = String::new(); let _ = rdr.read_line(&mut msg); let _ = write!(&stream, "OK"); let mut data = st.lock().unwrap(); data.msg = msg.trim().to_string(); stream.shutdown(Shutdown::Both).expect("socket to close"); } const UPDATE_FREQUENCY: u64 = 250; fn update_every_so_often(st: MTState) { loop { let so_often = time::Duration::from_millis(UPDATE_FREQUENCY); thread::sleep(so_often); { let data = st.lock().unwrap(); data.show(); } } } fn main() -> std::io::Result<()> { let st: State = State::init(); st.show(); let mtst = Arc::new(Mutex::new(st)); // start update thread { let mtst = mtst.clone(); thread::spawn(move || update_every_so_often(mtst)); } let _ = std::fs::remove_file("/home/cadey/tmp/cabytcini.sock")?; let listener = UnixListener::bind("/home/cadey/tmp/cabytcini.sock")?; for stream in listener.incoming() { match stream { Ok(stream) => { let mtst = mtst.clone(); thread::spawn(move || handle_client(stream, mtst)); } Err(err) => { break; } } } Ok(()) } struct State { msg: String, } impl fmt::Display for State { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.msg) } } impl State { fn init() -> State { State { msg: "".to_string(), } } fn show(&self) { let now = Local::now().format("%H:%M M%m %-d %a"); let xsr = XSetRoot::init(); if self.msg == "" { xsr.render(format!("{}", now)) } else { xsr.render(format!("{} | {}", self.msg, now)); } } }