radicle_cli/terminal/
cob.rs1use radicle::{
2 Profile,
3 cob::{
4 self,
5 cache::{MigrateCallback, MigrateProgress},
6 store::access::{ReadOnly, WriteAs},
7 },
8 prelude::NodeId,
9 profile,
10 storage::ReadRepository,
11};
12use radicle_term as term;
13
14use crate::terminal;
15
16pub const MIGRATION_HINT: &str = "run `rad cob migrate` to update your database";
18
19pub struct MigrateSpinner {
21 spinner: Option<term::Spinner>,
22}
23
24impl Default for MigrateSpinner {
25 fn default() -> Self {
27 Self { spinner: None }
28 }
29}
30
31impl MigrateCallback for MigrateSpinner {
32 fn progress(&mut self, progress: MigrateProgress) {
33 self.spinner
34 .get_or_insert_with(|| term::spinner("Migration in progress.."))
35 .message(format!(
36 "Migration {}/{} in progress.. ({}%)",
37 progress.migration.current(),
38 progress.migration.total(),
39 progress.rows.percentage()
40 ));
41
42 if progress.is_done() {
43 if let Some(spinner) = self.spinner.take() {
44 spinner.finish()
45 }
46 }
47 }
48}
49
50pub mod migrate {
52 use super::MigrateSpinner;
53
54 #[must_use]
56 pub fn spinner() -> MigrateSpinner {
57 MigrateSpinner::default()
58 }
59}
60
61pub fn patches<'a, Repo>(
63 profile: &Profile,
64 repository: &'a Repo,
65) -> Result<cob::patch::Cache<'a, Repo, ReadOnly, cob::cache::StoreReader>, anyhow::Error>
66where
67 Repo: ReadRepository + cob::Store<Namespace = NodeId>,
68{
69 profile.patches(repository).map_err(with_hint)
70}
71
72pub fn patches_mut<'a, 'b, Repo, Signer>(
76 profile: &Profile,
77 repository: &'a Repo,
78 signer: &'b Signer,
79) -> Result<cob::patch::Cache<'a, Repo, WriteAs<'b, Signer>, cob::cache::StoreWriter>, anyhow::Error>
80where
81 Repo: ReadRepository + cob::Store<Namespace = NodeId>,
82{
83 profile.patches_mut(repository, signer).map_err(with_hint)
84}
85
86pub fn issues<'a, Repo>(
88 profile: &Profile,
89 repository: &'a Repo,
90) -> Result<cob::issue::Cache<'a, Repo, ReadOnly, cob::cache::StoreReader>, anyhow::Error>
91where
92 Repo: ReadRepository + cob::Store<Namespace = NodeId>,
93{
94 profile.issues(repository).map_err(with_hint)
95}
96
97pub fn issues_mut<'a, 'b, Repo, Signer>(
101 profile: &Profile,
102 repository: &'a Repo,
103 signer: &'b Signer,
104) -> Result<cob::issue::Cache<'a, Repo, WriteAs<'b, Signer>, cob::cache::StoreWriter>, anyhow::Error>
105where
106 Repo: ReadRepository + cob::Store<Namespace = NodeId>,
107{
108 profile.issues_mut(repository, signer).map_err(with_hint)
109}
110
111fn with_hint(e: profile::Error) -> anyhow::Error {
113 #[allow(clippy::wildcard_enum_match_arm)]
116 match e {
117 profile::Error::CobsCache(cob::cache::Error::OutOfDate) => {
118 terminal::args::Error::with_hint(e, MIGRATION_HINT).into()
119 }
120 e => anyhow::Error::from(e),
121 }
122}