#![allow(dead_code)]
use anyhow::{anyhow, Result};
use serde::{Deserialize, Serialize};
use crate::IgnoreStore;
use crate::ProjectId;
use crate::RelativePath;
use crate::Repository;
pub struct RepositoryHandler<R: Repository> {
repository: R,
}
impl<R: Repository> RepositoryHandler<R> {
pub fn new(repository: R) -> Self {
Self { repository }
}
pub fn as_ignore_store(&self) -> &dyn IgnoreStore {
&self.repository
}
pub fn repository(&mut self) -> &mut R {
&mut self.repository
}
fn run(&mut self, mut operation: Operation) -> Result<()> {
operation.execute(&mut self.repository)?;
self.repository.insert_operation(&operation)
}
pub fn undo(&mut self) -> Result<()> {
let last_operation = self.repository.pop_last_operation()?;
let mut last_operation = last_operation.ok_or_else(|| anyhow!("Nothing to undo"))?;
last_operation.undo(&mut self.repository)
}
pub fn ignore(&mut self, word: &str) -> Result<()> {
self.run(Operation::Ignore(Ignore {
word: word.to_string(),
}))
}
pub fn ignore_for_extension(&mut self, word: &str, extension: &str) -> Result<()> {
self.run(Operation::IgnoreForExtension(IgnoreForExtension {
word: word.to_string(),
extension: extension.to_string(),
}))
}
pub fn ignore_for_project(&mut self, word: &str, project_id: ProjectId) -> Result<()> {
self.run(Operation::IgnoreForProject(IgnoreForProject {
word: word.to_string(),
project_id,
}))
}
pub fn ignore_for_path(
&mut self,
word: &str,
project_id: ProjectId,
path: &RelativePath,
) -> Result<()> {
self.run(Operation::IgnoreForPath(IgnoreForPath {
word: word.to_string(),
project_id,
path: path.clone(),
}))
}
}
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
pub enum Operation {
Ignore(Ignore),
IgnoreForExtension(IgnoreForExtension),
IgnoreForPath(IgnoreForPath),
IgnoreForProject(IgnoreForProject),
}
impl Operation {
fn execute<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
use Operation::*;
match self {
Ignore(o) => o.execute(repo),
IgnoreForExtension(o) => o.execute(repo),
IgnoreForPath(o) => o.execute(repo),
IgnoreForProject(o) => o.execute(repo),
}
}
fn undo<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
use Operation::*;
match self {
Ignore(o) => o.undo(repo),
IgnoreForExtension(o) => o.undo(repo),
IgnoreForPath(o) => o.undo(repo),
IgnoreForProject(o) => o.undo(repo),
}
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Ignore {
pub word: String,
}
impl Ignore {
fn execute<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
repo.ignore(&self.word)
}
fn undo<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
repo.remove_ignored(&self.word)
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct IgnoreForExtension {
word: String,
extension: String,
}
impl IgnoreForExtension {
fn execute<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
repo.ignore_for_extension(&self.word, &self.extension)
}
fn undo<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
repo.remove_ignored_for_extension(&self.word, &self.extension)
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct IgnoreForProject {
word: String,
project_id: ProjectId,
}
impl IgnoreForProject {
fn execute<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
repo.ignore_for_project(&self.word, self.project_id)
}
fn undo<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
repo.remove_ignored_for_project(&self.word, self.project_id)
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct IgnoreForPath {
word: String,
project_id: ProjectId,
path: RelativePath,
}
impl IgnoreForPath {
fn execute<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
repo.ignore_for_path(&self.word, self.project_id, &self.path)
}
fn undo<R: Repository>(&mut self, repo: &mut R) -> Result<()> {
repo.remove_ignored_for_path(&self.word, self.project_id, &self.path)
}
}