radicle_cli/terminal/
cob.rs1use radicle::{
2 cob::{
3 self,
4 cache::{MigrateCallback, MigrateProgress},
5 },
6 prelude::NodeId,
7 profile,
8 storage::ReadRepository,
9 Profile,
10};
11use radicle_term as term;
12
13use crate::terminal;
14
15pub const MIGRATION_HINT: &str = "run `rad cob migrate` to update your database";
17
18pub struct MigrateSpinner {
20 spinner: Option<term::Spinner>,
21}
22
23impl Default for MigrateSpinner {
24 fn default() -> Self {
26 Self { spinner: None }
27 }
28}
29
30impl MigrateCallback for MigrateSpinner {
31 fn progress(&mut self, progress: MigrateProgress) {
32 self.spinner
33 .get_or_insert_with(|| term::spinner("Migration in progress.."))
34 .message(format!(
35 "Migration {}/{} in progress.. ({}%)",
36 progress.migration.current(),
37 progress.migration.total(),
38 progress.rows.percentage()
39 ));
40
41 if progress.is_done() {
42 if let Some(spinner) = self.spinner.take() {
43 spinner.finish()
44 }
45 }
46 }
47}
48
49pub mod migrate {
51 use super::MigrateSpinner;
52
53 pub fn spinner() -> MigrateSpinner {
55 MigrateSpinner::default()
56 }
57}
58
59pub fn patches<'a, R>(
61 profile: &Profile,
62 repository: &'a R,
63) -> Result<cob::patch::Cache<cob::patch::Patches<'a, R>, cob::cache::StoreReader>, anyhow::Error>
64where
65 R: ReadRepository + cob::Store<Namespace = NodeId>,
66{
67 profile.patches(repository).map_err(with_hint)
68}
69
70pub fn patches_mut<'a, R>(
72 profile: &Profile,
73 repository: &'a R,
74) -> Result<cob::patch::Cache<cob::patch::Patches<'a, R>, cob::cache::StoreWriter>, anyhow::Error>
75where
76 R: ReadRepository + cob::Store<Namespace = NodeId>,
77{
78 profile.patches_mut(repository).map_err(with_hint)
79}
80
81pub fn issues<'a, R>(
83 profile: &Profile,
84 repository: &'a R,
85) -> Result<cob::issue::Cache<cob::issue::Issues<'a, R>, cob::cache::StoreReader>, anyhow::Error>
86where
87 R: ReadRepository + cob::Store<Namespace = NodeId>,
88{
89 profile.issues(repository).map_err(with_hint)
90}
91
92pub fn issues_mut<'a, R>(
94 profile: &Profile,
95 repository: &'a R,
96) -> Result<cob::issue::Cache<cob::issue::Issues<'a, R>, cob::cache::StoreWriter>, anyhow::Error>
97where
98 R: ReadRepository + cob::Store<Namespace = NodeId>,
99{
100 profile.issues_mut(repository).map_err(with_hint)
101}
102
103fn with_hint(e: profile::Error) -> anyhow::Error {
105 match e {
106 profile::Error::CobsCache(cob::cache::Error::OutOfDate) => {
107 anyhow::Error::from(terminal::args::Error::WithHint {
108 err: e.into(),
109 hint: MIGRATION_HINT,
110 })
111 }
112 e => anyhow::Error::from(e),
113 }
114}