use crate::*;
use alux_ext::ext;
use ambassador::delegatable_trait;
#[delegatable_trait]
pub trait SyncRunAlg: RsyncSorts {
type Error;
type Run;
fn start_sync(&self, command: &Self::Command) -> Result<Self::Run, Self::Error>;
fn next_sync_line(&self, run: &mut Self::Run) -> Result<Option<String>, Self::Error>;
fn finish_sync(&self, run: Self::Run) -> Result<(), Self::Error>;
}
#[delegatable_trait]
pub trait SyncWatchAlg: RsyncSorts {
fn watch_sync(&self, observation: &Self::Observation);
}
#[ext(name = SyncProgramExt)]
pub impl<This> This
where
This: SyncRunAlg + SyncWatchAlg + SyncChangeAlg + SyncObservationAlg + SyncObservationViewAlg,
This::Change: Clone,
{
fn run_sync(&self, command: &This::Command) -> Result<Vec<This::Change>, This::Error> {
let mut run = self.start_sync(command)?;
let mut changes = Vec::new();
while let Some(line) = self.next_sync_line(&mut run)? {
let observation = self.read_sync_line(&line);
self.watch_sync(&observation);
if let Some(change) = self.observation_change(&observation) {
changes.push(change.clone());
}
}
self.finish_sync(run)?;
Ok(changes)
}
}