knott 0.1.17

Fast Rust package manager helper for Arch Linux repos and the AUR
Documentation
use crate::transaction::{self, AurItemStatus, AurTransactionItem, Transaction, TransactionPhase};

use anyhow::Result;
use std::path::PathBuf;

pub(super) enum Journal<'a> {
    Durable(&'a mut Transaction),
    Memory(Transaction),
    None,
}

impl Journal<'_> {
    pub(super) fn tx(&self) -> Option<&Transaction> {
        match self {
            Self::Durable(tx) => Some(tx),
            Self::Memory(tx) => Some(tx),
            Self::None => None,
        }
    }

    fn tx_mut(&mut self) -> Option<&mut Transaction> {
        match self {
            Self::Durable(tx) => Some(tx),
            Self::Memory(tx) => Some(tx),
            Self::None => None,
        }
    }

    pub(super) fn set_phase(&mut self, phase: TransactionPhase) -> Result<()> {
        if let Some(tx) = self.tx_mut() {
            tx.phase = phase;
        }
        self.save()
    }

    pub(super) fn set_repo_deps(&mut self, deps: Vec<String>, as_deps: bool) -> Result<()> {
        if let Some(tx) = self.tx_mut() {
            tx.repo_deps = deps;
            tx.options.repo_deps_as_deps = as_deps;
        }
        self.save()
    }

    pub(super) fn write_plan(
        &mut self,
        repo_deps: Vec<String>,
        aur_items: Vec<AurTransactionItem>,
        unresolved: Vec<String>,
    ) -> Result<()> {
        if let Some(tx) = self.tx_mut() {
            tx.repo_deps = repo_deps;
            tx.options.repo_deps_as_deps = true;
            tx.aur_items = aur_items;
            tx.unresolved = unresolved;
            tx.phase = TransactionPhase::AurPlanWritten;
        }
        self.save()
    }

    pub(super) fn base_status(&self, base: &str) -> Option<AurItemStatus> {
        self.tx()?
            .aur_items
            .iter()
            .find(|item| item.base == base)
            .map(|item| item.status)
    }

    pub(super) fn base_build_dir(&self, base: &str) -> Option<PathBuf> {
        self.tx()?
            .aur_items
            .iter()
            .find(|item| item.base == base)
            .map(|item| item.build_dir.clone())
    }

    pub(super) fn base_artifacts(&self, base: &str) -> Vec<PathBuf> {
        self.tx()
            .and_then(|tx| {
                tx.aur_items
                    .iter()
                    .find(|item| item.base == base && !item.artifacts.is_empty())
            })
            .map(|item| item.artifacts.clone())
            .unwrap_or_default()
    }

    pub(super) fn set_base_status(&mut self, base: &str, status: AurItemStatus) -> Result<()> {
        if let Some(tx) = self.tx_mut() {
            for item in &mut tx.aur_items {
                if item.base == base {
                    item.status = status;
                }
            }
        }
        self.save()
    }

    pub(super) fn set_base_artifacts(&mut self, base: &str, artifacts: Vec<PathBuf>) -> Result<()> {
        if let Some(tx) = self.tx_mut() {
            for item in &mut tx.aur_items {
                if item.base == base {
                    item.artifacts = artifacts.clone();
                }
            }
        }
        self.save()
    }

    pub(super) fn mark_failed(&mut self, err: impl std::fmt::Display) -> Result<()> {
        match self {
            Self::Durable(tx) => transaction::mark_failed(tx, err),
            Self::Memory(tx) => {
                tx.phase = TransactionPhase::Failed;
                tx.last_error = Some(err.to_string());
                Ok(())
            }
            Self::None => Ok(()),
        }
    }

    pub(super) fn mark_completed(&mut self) -> Result<()> {
        match self {
            Self::Durable(tx) => transaction::mark_completed(tx),
            Self::Memory(tx) => {
                tx.phase = TransactionPhase::Completed;
                tx.last_error = None;
                Ok(())
            }
            Self::None => Ok(()),
        }
    }

    fn save(&self) -> Result<()> {
        match self {
            Self::Durable(tx) => transaction::save_current(tx),
            Self::Memory(_) | Self::None => Ok(()),
        }
    }
}