reovim_plugin_notification/
progress.rs1#[derive(Debug, Clone)]
7pub struct ProgressNotification {
8 pub id: String,
10 pub title: String,
12 pub source: String,
14 pub progress: Option<u8>,
16 pub detail: Option<String>,
18 pub complete: bool,
20}
21
22impl ProgressNotification {
23 #[must_use]
25 pub fn new(id: impl Into<String>, title: impl Into<String>, source: impl Into<String>) -> Self {
26 Self {
27 id: id.into(),
28 title: title.into(),
29 source: source.into(),
30 progress: None,
31 detail: None,
32 complete: false,
33 }
34 }
35
36 #[must_use]
38 pub fn with_progress(mut self, progress: u8) -> Self {
39 self.progress = Some(progress.min(100));
40 self
41 }
42
43 #[must_use]
45 pub fn with_detail(mut self, detail: impl Into<String>) -> Self {
46 self.detail = Some(detail.into());
47 self
48 }
49
50 #[must_use]
52 pub const fn completed(mut self) -> Self {
53 self.complete = true;
54 self.progress = Some(100);
55 self
56 }
57
58 #[must_use]
60 pub const fn is_indeterminate(&self) -> bool {
61 self.progress.is_none()
62 }
63}
64
65#[derive(Debug, Clone)]
67pub struct ProgressBarConfig {
68 pub width: u16,
70 pub filled_char: char,
72 pub empty_char: char,
74}
75
76impl Default for ProgressBarConfig {
77 fn default() -> Self {
78 Self {
79 width: 20,
80 filled_char: '█',
81 empty_char: '░',
82 }
83 }
84}
85
86impl ProgressBarConfig {
87 #[must_use]
89 #[allow(clippy::cast_possible_truncation)]
90 pub fn render(&self, progress: Option<u8>) -> String {
91 progress.map_or_else(
92 || "⣷⣯⣟⡿⢿⣻⣽⣾".chars().next().unwrap_or('◌').to_string(),
93 |pct| {
94 let filled = (u16::from(pct.min(100)) * self.width / 100) as usize;
95 let empty = (self.width as usize).saturating_sub(filled);
96 format!(
97 "{}{}",
98 self.filled_char.to_string().repeat(filled),
99 self.empty_char.to_string().repeat(empty)
100 )
101 },
102 )
103 }
104}