cloc 0.6.2

Count, or compute differences of, lines of source code and comments.
#![allow(clippy::mutex_atomic)]
use std::io::prelude::*;
use std::io::stdout;
use std::sync::{Arc, Condvar, Mutex};
use std::thread::{sleep, spawn};
use std::time::Duration;

#[derive(Debug, Default)]
pub struct Spinner {
    cvar: Arc<Condvar>,
    lock: Arc<Mutex<bool>>,
}

impl Spinner {
    pub fn new() -> Self {
        Self {
            cvar: Arc::new(Condvar::new()),
            lock: Arc::new(Mutex::new(false)),
        }
    }

    pub fn start(&self) {
        let Self { cvar, lock } = self;
        let pair = (Arc::clone(&lock), Arc::clone(&cvar));
        spawn(move || {
            let mut out = stdout();
            for c in vec!['|', '/', '-', '\\'].iter().cycle() {
                let status = format!("{} computing", c);
                let _ = out.write_all(status.as_bytes());
                let _ = out.flush();
                let _ = out.write_all("\x08".repeat(status.len()).as_bytes());
                sleep(Duration::from_millis(50));

                let (lock, cvar) = &pair;

                if let Ok(mut started) = lock.lock() {
                    if let Ok(result) = cvar.wait_timeout(started, Duration::from_millis(100)) {
                        started = result.0;
                        if *started {
                            break;
                        }
                    }
                }
            }
        });
    }

    pub fn stop(&self) {
        let Self { cvar, lock } = self;
        if let Ok(mut started) = lock.lock() {
            *started = true;
            cvar.notify_one();
        }
    }
}