lookas 1.10.0

Perception aligned terminal-based audio spectrum visualizer
Documentation
use anyhow::Result;
use lookas::config::Config;
use std::{
    sync::mpsc::{self, Receiver, TryRecvError},
    thread,
    time::Duration,
};

const CONFIG_WATCH_INTERVAL: Duration = Duration::from_millis(125);

pub struct ConfigWatch {
    rx: Receiver<Result<Config>>,
}

impl ConfigWatch {
    #[must_use]
    pub fn spawn(initial_cfg: Config) -> Self {
        let (tx, rx) = mpsc::channel();

        thread::spawn(move || {
            let mut current_cfg = initial_cfg;

            loop {
                thread::sleep(CONFIG_WATCH_INTERVAL);

                match Config::load() {
                    Ok(next_cfg) => {
                        if next_cfg == current_cfg {
                            continue;
                        }

                        current_cfg = next_cfg.clone();
                        if tx.send(Ok(next_cfg)).is_err() {
                            break;
                        }
                    }
                    Err(error) => {
                        let _ = tx.send(Err(error));
                        break;
                    }
                }
            }
        });

        Self { rx }
    }

    pub fn latest(&self) -> Result<Option<Config>> {
        let mut latest = None;

        loop {
            match self.rx.try_recv() {
                Ok(Ok(cfg)) => latest = Some(cfg),
                Ok(Err(error)) => return Err(error),
                Err(TryRecvError::Empty) => return Ok(latest),
                Err(TryRecvError::Disconnected) => {
                    anyhow::bail!("config watcher stopped");
                }
            }
        }
    }
}