treeflow 0.2.1

CLI tool for simplified Git worktree management to speed up switching contexts when working collaboratively.
Documentation
use crate::core::config::Config;
use crate::core::work_item::WorkItem;
use crate::utils::errors::CustomError;
use crate::utils::{git, PathBufExtensions, Return};
use serde::{Deserialize, Serialize};
use std::env;
use std::path::PathBuf;

#[derive(Serialize)]
#[derive(Deserialize)]
#[derive(Clone)]
pub struct Project {
    pub repository: PathBuf,
    pub worktrees: PathBuf,
}

impl Project {
    pub fn work_on(&self, config: Config, work_type: &str, work_name: &str) -> Result<Return, CustomError> {
        let work_branch = config.work_type_from_name(work_type)?.prefix.to_string() + &work_name;

        self.review(&work_branch)
    }

    pub fn review(&self, work_branch: &str) -> Result<Return, CustomError> {
        let work_dir = self.worktrees.join(&work_branch);

        if work_dir.exists() && !git::is_valid_worktree(&work_dir) {
            Err(CustomError::Custom(format!("Worktree directory exists, but is missing a .git directory at '{}'.", work_dir.display())))
        } else {
            if !work_dir.exists() {
                git::checkout_new_or_existing_worktree(&work_dir, &work_branch)?;
            }

            Ok(Return::Cd { path: work_dir.to_path_buf() })
        }
    }

    pub fn current_work_item(&self) -> Result<WorkItem, CustomError> {
        if env::current_dir()? == self.repository {
            return Err(CustomError::Custom("Current directory is the main working tree".to_string()));
        }

        let current_dir = env::current_dir().map_err(|error| CustomError::IoError(error))?;
        let worktrees_dir_len = self.worktrees.to_str_result()?.len() + 1;
        let name = &current_dir.to_str_result()?[worktrees_dir_len..];
        Ok(WorkItem { name: name.to_string(), path: current_dir })
    }
}