use std::path::Path;
use weavatrix_refactor_plan::EditPlan;
use crate::{
WorktreePlan,
error::{TransactionPhase, WorktreeError, WorktreeErrorCode},
filesystem::FsRoot,
operation::{
PreparedWorktreeTransaction, RetainedApplyReport, UndoId, UndoReceipt, UndoRetention,
UndoRollbackReport, UndoStoreUsage, dry_run_operation_plan, prepare_operation_plan,
recover_operation_transaction, undo_discard, undo_receipts, undo_rollback, undo_usage,
},
options::WorktreeOptions,
report::{
ApplyReport, DryRunReport, RecoveryReport, WorktreeApplyReport, WorktreeDryRunReport,
},
transaction::{
PreparedTransaction, dry_run_report, prepare_transaction, project_plan, recover_transaction,
},
};
pub struct Worktree {
root: FsRoot,
options: WorktreeOptions,
}
impl Worktree {
pub fn open(root: impl AsRef<Path>) -> Result<Self, WorktreeError> {
Self::open_with(root, WorktreeOptions::default())
}
pub fn open_with(
root: impl AsRef<Path>,
options: WorktreeOptions,
) -> Result<Self, WorktreeError> {
options.validate()?;
let root = FsRoot::open(root.as_ref()).map_err(|error| {
WorktreeError::with_source(
WorktreeErrorCode::InvalidRoot,
TransactionPhase::Open,
"failed to open a real worktree root capability",
error,
)
})?;
Ok(Self { root, options })
}
#[must_use]
pub const fn options(&self) -> WorktreeOptions {
self.options
}
pub fn dry_run(&self, plan: &EditPlan) -> Result<DryRunReport, WorktreeError> {
let projected = project_plan(&self.root, self.options, plan)?;
Ok(dry_run_report(plan, &projected))
}
pub fn prepare(&self, plan: &EditPlan) -> Result<PreparedTransaction, WorktreeError> {
prepare_transaction(&self.root, self.options, plan)
}
pub fn apply(&self, plan: &EditPlan) -> Result<ApplyReport, WorktreeError> {
self.prepare(plan)?.commit()
}
pub fn dry_run_plan(&self, plan: &WorktreePlan) -> Result<WorktreeDryRunReport, WorktreeError> {
dry_run_operation_plan(&self.root, self.options, plan)
}
pub fn prepare_plan(
&self,
plan: &WorktreePlan,
) -> Result<PreparedWorktreeTransaction, WorktreeError> {
prepare_operation_plan(&self.root, self.options, plan)
}
pub fn apply_plan(&self, plan: &WorktreePlan) -> Result<WorktreeApplyReport, WorktreeError> {
self.prepare_plan(plan)?.commit()
}
pub fn apply_plan_retained(
&self,
plan: &WorktreePlan,
retention: UndoRetention,
) -> Result<RetainedApplyReport, WorktreeError> {
self.prepare_plan(plan)?.commit_retained(retention)
}
pub fn undo_receipts(&self) -> Result<Vec<UndoReceipt>, WorktreeError> {
undo_receipts(&self.root, self.options)
}
pub fn undo_usage(&self) -> Result<UndoStoreUsage, WorktreeError> {
undo_usage(&self.root, self.options)
}
pub fn rollback_undo(&self, id: &UndoId) -> Result<UndoRollbackReport, WorktreeError> {
undo_rollback(&self.root, self.options, id)
}
pub fn discard_undo(&self, id: &UndoId) -> Result<usize, WorktreeError> {
undo_discard(&self.root, self.options, id)
}
pub fn recover(&self) -> Result<RecoveryReport, WorktreeError> {
if let Some(report) = recover_operation_transaction(&self.root, self.options)? {
return Ok(report);
}
recover_transaction(&self.root, self.options)
}
}