//! An abstraction for worker threads.
//!
//! The abstraction provided some consistency on how worker threads
//! are implemented and used, as well as logging. A worker thread does
//! what it does. The abstraction is not meant to constrain that.

use std::thread::{JoinHandle, spawn};

use crate::logger;

/// Start a new thread. Caller must catch the thread handle and
/// join it to wait for thread to end.
pub fn start_thread<W: Worker + 'static>(mut o: W) -> JoinHandle<Result<(), W::Error>> {
    spawn(move || {
        logger::worker_start(W::NAME);
        let result = o.work();
        logger::worker_end(W::NAME, &result);
        result
    })
}

/// A worker thread.
pub trait Worker: Send {
    /// Name of thread, or kind of thread. Used for logging only.
    const NAME: &'static str;

    /// Type of error from this worker.
    type Error: std::error::Error + Send;

    /// Do the work the thread is supposed to do.
    fn work(&mut self) -> Result<(), Self::Error>;
}
