Expand description
§rsynko-rsync
rsynko-rsync defines the transfer of one path from one place to another. That path may be a single file or a whole folder, and the difference is not this specification’s business: a folder is one thing, not a collection of files that happen to travel together. Either way it is named at both ends, it is stated before it is performed, and it states back exactly what it would do.
The specification owns the command, including every argument, because the command is the request. An interpreter starts it, hands back what it wrote, and reports how it ended; it never decides what a transfer should ask for.
§Specification surface
RsyncSorts states the type families every class shares: an endpoint, a command, one thing a running transfer states, and one path it would change. An interpreter ties all four at once and no class re-declares any of them.
An endpoint is defined by what it names and observed through what it states:
RsyncEndpointAlg::endpointdefines one from an account, a machine, and a path;RsyncEndpointViewAlgobserves those three back;RsyncEndpointExt::read_endpointderives one from submitted text, andendpoint_textstates it back the way the transfer program is given it.
Reading and stating are inverse, which is the law that keeps a submitted source recognizable after it has been through the vocabulary.
Only three shapes name a path on another machine: a daemon URL, and a machine and a path separated by a colon with nothing path-like before it. A text naming any other scheme names a resource somewhere else, which is what keeps a media URL from being read as a path to transfer.
Composing those meanings is an extension, and its bounds are the specification. Nothing here names a record, a program, or a process:
use alux_ext::ext;
use rsynko_rsync::{
RsyncEndpointAlg, RsyncEndpointExt, RsyncEndpointViewAlg, SyncCommandAlg, SyncCommandExt,
SyncCommandViewAlg, SyncMode,
};
#[ext(name = ExampleFolderExt)]
impl<This> This
where
This: RsyncEndpointAlg + RsyncEndpointViewAlg + SyncCommandAlg + SyncCommandViewAlg,
{
/// States the rehearsal of one submitted path into the place it would come to rest.
fn example_rehearsal(&self, submitted: &str, into: &str) -> Option<This::Command> {
let source = self.read_endpoint(submitted);
// A path already here is not something somebody asked to be brought here.
self.endpoint_remote(&source).then(|| {
self.transfer_command(&source, &self.read_endpoint(into), SyncMode::rehearsal())
})
}
/// Names what a submitted source would arrive as, under a chosen parent.
fn example_destination(&self, submitted: &str, parent: &str) -> String {
format!(
"{parent}/{}",
self.endpoint_name(&self.read_endpoint(submitted))
)
}
}SyncCommandAlg::sync_command defines the command; SyncCommandViewAlg observes the program and its arguments. SyncCommandExt::transfer_command derives the whole command from the two ends and a SyncMode, and command_rehearses and command_mirrors observe what the derived command is allowed to do. Each end is stated exactly as it was written: a source ending with a separator names the contents of a folder, and one without names the path itself, which comes to rest inside the destination. Both are wanted, so neither is invented.
A transfer has a great many arguments and almost nobody wants an arbitrary combination of them: what people want is one of a handful of familiar jobs. SyncProfile names thirteen, each after what it does rather than what it is for, and each states exactly the arguments that make it do that — mirror asks for --delete, mirror-keeping for --compress --delete --backup, mirror-whole for --whole-file --delete, compare-content for --checksum, resume for --inplace --append-verify. SyncProfile::key names one, summary says what it does and then what that is usually good for, and SyncProfile::read reads a name back, so a chosen way survives being written down.
A running transfer states two kinds of thing, and a great many lines that are neither. SyncObservationAlg defines all three, SyncObservationViewAlg observes which one a line turned out to be, and SyncReadExt::read_sync_line derives that from what the program wrote. A changed path is defined by SyncChangeAlg::sync_change and observed through the manager’s own PlannedChangeAlg, so what a transfer says it would do and what a reader is shown are the same statement.
§Running one
SyncRunAlg is the whole of what an interpreter supplies: start a command, read the next line, and state how it ended. SyncWatchAlg states what to do with each observation as it arrives. SyncProgramExt::run_sync composes them into one transfer that reports progress while it runs and states every change it named when it ends.
The command carries the rehearsal, so rehearsing and transferring are one program run two ways rather than two programs. What a caller does with the result is another extension over the same bounds:
use alux_ext::ext;
use rsynko_manager::{ChangeKind, PlannedChangeAlg};
use rsynko_rsync::{
SyncChangeAlg, SyncObservationAlg, SyncObservationViewAlg, SyncProgramExt, SyncRunAlg,
SyncWatchAlg,
};
#[ext(name = ExampleReportExt)]
impl<This> This
where
This: SyncRunAlg + SyncWatchAlg + SyncChangeAlg + SyncObservationAlg + SyncObservationViewAlg,
This::Change: PlannedChangeAlg + Clone,
{
/// Counts what one transfer would alter, and what it would leave exactly as it is.
///
/// # Errors
///
/// Returns the failure that ran the transfer.
fn example_report(&self, command: &This::Command) -> Result<(usize, usize), This::Error> {
let changes = self.run_sync(command)?;
let altered = changes
.iter()
.filter(|change| change.change_kind().alters())
.count();
Ok((altered, changes.len() - altered))
}
/// Observes whether one transfer would remove anything at the destination.
///
/// # Errors
///
/// Returns the failure that ran the transfer.
fn example_removes(&self, command: &This::Command) -> Result<bool, This::Error> {
Ok(self
.run_sync(command)?
.iter()
.any(|change| change.change_kind() == ChangeKind::Delete))
}
}A reference interpreter tying the four sorts to inspectable records lives in rsynko-memory, and rsynko-process supplies the two capabilities that actually run one.
§Laws
SyncLaws::sync_laws checks that an endpoint states back the text it was read from and agrees about which machine it rests on; that a rehearsal states it changes nothing while a transfer does not, and a mirroring transfer states it removes while one that only adds does not; that every itemized shape states the change it denotes and progress is not one; and that running a transfer states every change its lines named, in the order they arrived. SyncLawFixture supplies what a scenario cannot author for itself: the lines the next transfer will state.
Modules§
- sync_
profile - States what each
SyncProfilemaps to, and reads it back.
Macros§
- ambassador_
impl_ Rsync Endpoint Alg - A macro to be used by
ambassador::Delegateto delegateRsyncEndpointAlgA macro to be used byambassador::Delegateto delegateRsyncEndpointAlgA macro to be used byambassador::Delegateto delegateRsyncEndpointAlg - ambassador_
impl_ Rsync Endpoint View Alg - A macro to be used by
ambassador::Delegateto delegateRsyncEndpointViewAlgA macro to be used byambassador::Delegateto delegateRsyncEndpointViewAlgA macro to be used byambassador::Delegateto delegateRsyncEndpointViewAlg - ambassador_
impl_ Sync Change Alg - A macro to be used by
ambassador::Delegateto delegateSyncChangeAlgA macro to be used byambassador::Delegateto delegateSyncChangeAlgA macro to be used byambassador::Delegateto delegateSyncChangeAlg - ambassador_
impl_ Sync Command Alg - A macro to be used by
ambassador::Delegateto delegateSyncCommandAlgA macro to be used byambassador::Delegateto delegateSyncCommandAlgA macro to be used byambassador::Delegateto delegateSyncCommandAlg - ambassador_
impl_ Sync Command View Alg - A macro to be used by
ambassador::Delegateto delegateSyncCommandViewAlgA macro to be used byambassador::Delegateto delegateSyncCommandViewAlgA macro to be used byambassador::Delegateto delegateSyncCommandViewAlg - ambassador_
impl_ Sync Observation Alg - A macro to be used by
ambassador::Delegateto delegateSyncObservationAlgA macro to be used byambassador::Delegateto delegateSyncObservationAlgA macro to be used byambassador::Delegateto delegateSyncObservationAlg - ambassador_
impl_ Sync Observation View Alg - A macro to be used by
ambassador::Delegateto delegateSyncObservationViewAlgA macro to be used byambassador::Delegateto delegateSyncObservationViewAlgA macro to be used byambassador::Delegateto delegateSyncObservationViewAlg - ambassador_
impl_ Sync RunAlg - A macro to be used by
ambassador::Delegateto delegateSyncRunAlgA macro to be used byambassador::Delegateto delegateSyncRunAlgA macro to be used byambassador::Delegateto delegateSyncRunAlg - ambassador_
impl_ Sync Watch Alg - A macro to be used by
ambassador::Delegateto delegateSyncWatchAlgA macro to be used byambassador::Delegateto delegateSyncWatchAlgA macro to be used byambassador::Delegateto delegateSyncWatchAlg
Structs§
- Sync
Mode - Selects what one transfer is allowed to do.
Enums§
- Sync
Profile - Selects one commonly wanted way of transferring a path.
Constants§
- DELETION_
MARK - Names the mark a removal states instead of a change flag.
- FIELD_
MARK - Names the field separator each stated path is written with.
- RSYNC_
SCHEME - Names the scheme a daemon endpoint states itself with.
- RSYNC_
WORD - Names the word a whole transfer command begins with.
- SYNC_
MIRROR - States that the destination is made to match the source exactly.
- SYNC_
OUT_ FORMAT - States each transferred path as its change, its byte count, and its name.
- SYNC_
PROGRAM - Names the program a transfer is performed by.
- SYNC_
REHEARSAL - States that the transfer changes nothing and only says what it would do.
Traits§
- Rsync
Endpoint Alg - Provides the carrier and constructor for one end of a transfer.
- Rsync
Endpoint Ext - Derives an endpoint from what somebody submitted, and states one back.
- Rsync
Endpoint View Alg - Specifies what one endpoint states about itself.
- Rsync
Sorts - The sorts of transfer meaning — the type families the transfer algebra classes share.
- Sync
Change Alg - Provides the carrier and constructor for one path a transfer would change.
- Sync
Command Alg - Provides the carrier and constructor for exactly the command one transfer runs.
- Sync
Command Ext - Derives the command one folder transfer runs from the ends it joins.
- Sync
Command View Alg - Specifies what one command states about itself.
- Sync
LawFixture - Supplies the running transfer a scenario cannot author for itself.
- Sync
Laws - Authors the folder-transfer laws.
- Sync
Observation Alg - Provides the carriers and constructors for what a running transfer states.
- Sync
Observation View Alg - Specifies what one observation of a running transfer states.
- Sync
Program Ext - Derives one whole transfer from starting it, reading it, and finishing it.
- Sync
Read Ext - Derives what one line a running transfer wrote states.
- Sync
RunAlg - Specifies running one transfer command and reading what it states.
- Sync
Watch Alg - Specifies what an interpreter does with each thing a running transfer states.