Skip to main content

coven/
storage_setup_step.rs

1//! The steps of setting up storage, which a host draws instead of a bare
2//! spinner (api.md E1, E5).
3
4use coven_database::LoadStep;
5use coven_foundation::progress::{Progress, ProgressReport};
6use std::future::Future;
7
8/// A step of setting up storage, in the order they run. Which steps run
9/// depends on the provider and on whether setup creates the store. A step
10/// other than `Loading` is one unit, done when it ends. Setup can be
11/// cancelled until `CreatingStore` or `RecordingAccess` begins, its point of
12/// no return (§11.6).
13#[derive(Clone, Debug, PartialEq, Eq)]
14pub enum StorageSetupStep {
15    /// Creating the store in a location it needs to itself (a Dropbox shared
16    /// folder, a OneDrive folder, or an S3 bucket): listing the location's
17    /// root to check it holds nothing but this store (§20.3).
18    CheckingLocation,
19    /// S3: probing the service with fresh objects for the settings the
20    /// location needs, and checking them against what it does (§20.8).
21    DetectingSettings,
22    /// iCloud, creating the store: reading the account and saving the
23    /// store's zone.
24    PreparingZone,
25    /// Dropbox or OneDrive: reading the signed-in account's name.
26    ReadingAccount,
27    /// Connecting, reading a Dropbox or OneDrive folder's name and web
28    /// address (§20.2), then checking the provider with a fresh sealed
29    /// object it must create once, read back and delete.
30    Connecting,
31    /// Creating the store, past the point of no return: claiming the
32    /// location where it holds one store (§20.3), then slot 1, which
33    /// publishes it.
34    CreatingStore,
35    /// Reconnecting: opening this member's store keys and loading what other
36    /// devices published, each of loading's steps with its count (§13.4).
37    Loading(LoadStep),
38    /// Reconnecting with changed provider access, past the point of no
39    /// return: publishing it as `Set access`.
40    RecordingAccess,
41}
42
43/// Run `work` as the one unit of `step`, done when it succeeds.
44pub(crate) async fn single<T, E>(
45    progress: &mut ProgressReport<StorageSetupStep>,
46    step: StorageSetupStep,
47    work: impl Future<Output = Result<T, E>>,
48) -> Result<T, E> {
49    progress.begin(step, 1);
50    let output = work.await?;
51    progress.done(1);
52    Ok(output)
53}
54
55/// A load's progress, as the part of setup it is.
56pub(crate) fn loading(progress: Progress<LoadStep>) -> Progress<StorageSetupStep> {
57    Progress {
58        step: StorageSetupStep::Loading(progress.step),
59        done: progress.done,
60        total: progress.total,
61    }
62}