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 #[must_use]
55 pub fn spinner() -> MigrateSpinner {
56 MigrateSpinner::default()
57 }
58}
59
60pub fn patches<'a, R>(
62 profile: &Profile,
63 repository: &'a R,
64) -> Result<cob::patch::Cache<cob::patch::Patches<'a, R>, cob::cache::StoreReader>, anyhow::Error>
65where
66 R: ReadRepository + cob::Store<Namespace = NodeId>,
67{
68 profile.patches(repository).map_err(with_hint)
69}
70
71pub fn patches_mut<'a, R>(
73 profile: &Profile,
74 repository: &'a R,
75) -> Result<cob::patch::Cache<cob::patch::Patches<'a, R>, cob::cache::StoreWriter>, anyhow::Error>
76where
77 R: ReadRepository + cob::Store<Namespace = NodeId>,
78{
79 profile.patches_mut(repository).map_err(with_hint)
80}
81
82pub fn issues<'a, R>(
84 profile: &Profile,
85 repository: &'a R,
86) -> Result<cob::issue::Cache<cob::issue::Issues<'a, R>, cob::cache::StoreReader>, anyhow::Error>
87where
88 R: ReadRepository + cob::Store<Namespace = NodeId>,
89{
90 profile.issues(repository).map_err(with_hint)
91}
92
93pub fn issues_mut<'a, R>(
95 profile: &Profile,
96 repository: &'a R,
97) -> Result<cob::issue::Cache<cob::issue::Issues<'a, R>, cob::cache::StoreWriter>, anyhow::Error>
98where
99 R: ReadRepository + cob::Store<Namespace = NodeId>,
100{
101 profile.issues_mut(repository).map_err(with_hint)
102}
103
104fn with_hint(e: profile::Error) -> anyhow::Error {
106 #[allow(clippy::wildcard_enum_match_arm)]
109 match e {
110 profile::Error::CobsCache(cob::cache::Error::OutOfDate) => {
111 terminal::args::Error::with_hint(e, MIGRATION_HINT).into()
112 }
113 e => anyhow::Error::from(e),
114 }
115}