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}