nofi 0.2.4

A notification daemon for Rofi
Documentation
use crate::error::Result;
use std::io::prelude::*;
use std::os::unix::net::UnixListener;
use std::sync::{Arc, RwLock};
use std::thread;
use std::time::Duration;
use std::{fs, usize};
use xdg::BaseDirectories;

pub struct Socket {
    pub count: Arc<RwLock<(usize, usize)>>,
}

impl Clone for Socket {
    fn clone(&self) -> Self {
        Self {
            count: Arc::clone(&self.count),
        }
    }
}

impl Socket {
    pub fn init(xdg_dirs: &BaseDirectories) -> Result<Self> {
        let socket_path = xdg_dirs.place_runtime_file("socket")?;

        if socket_path.exists() {
            fs::remove_file(&socket_path)?;
        }

        let stream = UnixListener::bind(&socket_path)?;
        let count: (usize, usize) = (0, 0);
        let count = Arc::new(RwLock::new(count));
        let count_cloned = count.clone();

        println!("UNIX socket listening at {}", socket_path.display());

        thread::spawn(move || loop {
            for mut client in stream.incoming().flatten() {
                let mut response = String::new();
                client
                    .set_read_timeout(Some(Duration::from_millis(10)))
                    .unwrap();

                let _read = client.read_to_string(&mut response);

                let (normal, urgent) = *count_cloned.read().unwrap();
                let message = format!("{},{}", normal, urgent);

                match client.write(message.as_bytes()) {
                    Ok(_) => tracing::debug!("Sent counts: {}", message),
                    Err(e) => tracing::error!("Error sending notification counts: {}", e),
                }
            }
        });

        Ok(Self { count })
    }

    pub fn update(&self, counts: (usize, usize)) {
        let mut count = self.count.write().unwrap();
        *count = counts;
    }
}