use crate::{
    database::{Database, Error, Result},
    entities::{Client, Company, Job, Worker},
    jobber::*,
};

impl JobberEdit for Database {
    fn edit_company<T>(&mut self, f: impl FnOnce(&mut Company) -> Result<T>) -> Result<T> {
        match &mut self.company {
            Some(company) => f(company),
            None => Ok(Err(Error::NoCompany)?),
        }
    }

    fn edit_worker<T>(&mut self, id: &str, f: impl FnOnce(&mut Worker) -> Result<T>) -> Result<T> {
        match self.workers.get_mut(id) {
            Some(worker) => f(worker),
            None => Err(Error::WorkerNotFound(id.into())),
        }
    }

    fn edit_client<T>(&mut self, id: &str, f: impl FnOnce(&mut Client) -> Result<T>) -> Result<T> {
        match self.clients.get_mut(id) {
            Some(client) => f(client),
            None => Err(Error::ClientNotFound(id.into())),
        }
    }

    fn edit_job<T>(&mut self, pos: usize, f: impl FnOnce(&mut Job) -> Result<T>) -> Result<T> {
        match self.jobs.get_mut(pos) {
            Some(job) => f(job),
            None => Err(Error::JobNotFound(pos)),
        }
    }

    fn edit_tag<T>(
        &mut self,
        name: &str,
        f: impl FnOnce(&mut crate::entities::Tag) -> Result<T>,
    ) -> Result<T> {
        match self.tags.get_mut(name) {
            Some(tag) => f(tag),
            None => Err(Error::TagNotFound(name.to_string())),
        }
    }
}
