termprogress/
silent.rs

1//! A silent progress bar and spinner that does nothing.
2//!
3//! Useful for when progress bars are optional.
4
5use super::*;
6
7
8/// An implementor for the `Display`, `ProgressBar`, `Spinner`, and `WithTitle` that does nothing.
9///
10/// It also implements `Display::println()` and `Display::eprintln()` to do nothing as well.
11#[derive(Debug)]
12pub struct Silent;
13
14impl Display for Silent
15{
16    #[inline] fn println(&self, _: &str){}
17    #[inline] fn eprintln(&self, _: &str){}
18    #[inline] fn refresh(&self){}
19    #[inline] fn blank(&self){}
20    #[inline] fn get_title(&self) -> &str{""}
21    #[inline] fn set_title(&mut self, _: &str){}
22    #[inline] fn update_dimensions(&mut self, _:usize){}
23}
24
25impl ProgressBar for Silent
26{
27    #[inline] fn set_progress(&mut self, _:f64){}
28    #[inline] fn get_progress(&self) -> f64{0.0}
29}
30
31impl Spinner for Silent
32{
33    #[inline] fn bump(&mut self){}
34}
35
36impl WithTitle for Silent
37{
38    #[inline] fn with_title(self, _: impl AsRef<str>) -> Self{self}
39    #[inline] fn add_title(&mut self, _: impl AsRef<str>) {}
40    #[inline] fn update(&mut self) {}
41    #[inline] fn complete(self) {}
42}
43
44/// An enum wrapper for a progress bar or spinner that might be silent.
45#[derive(Debug)]
46pub enum MaybeSilent<T>
47{
48    /// There is no progress
49    Silent,
50    /// There is progress
51    Loud(T),
52}
53
54impl<T> Display for MaybeSilent<T>
55where T: Display
56{
57    
58    fn refresh(&self)
59    {
60	if let Self::Loud(this) = self {
61	    this.refresh();
62	}
63    }
64    fn blank(&self)
65    {
66	
67	if let Self::Loud(this) = self {
68	    this.blank();
69	}
70    }
71    fn println(&self, string: &str)
72    {	
73	if let Self::Loud(this) = self {
74	    this.println(string);
75	}
76    }
77    fn eprintln(&self, string: &str)
78    {
79	if let Self::Loud(this) = self {
80	    this.eprintln(string)
81	}
82    }
83
84    fn get_title(&self) -> &str
85    {
86	if let Self::Loud(this) = self {
87	    this.get_title()
88	} else {
89	    ""
90	}
91    }
92    fn set_title(&mut self, from: &str)
93    {
94	if let Self::Loud(this) = self {
95	    this.set_title(from);
96	}
97    }
98
99    fn update_dimensions(&mut self, to: usize)
100    {
101	if let Self::Loud(this) = self {
102	    this.update_dimensions(to)
103	}
104    }
105}
106
107
108impl<T> ProgressBar for MaybeSilent<T>
109    where T: ProgressBar
110{
111    fn set_progress(&mut self, value: f64)
112    {
113	if let Self::Loud(this) = self {
114	    this.set_progress(value)
115	}
116    }
117    fn get_progress(&self) -> f64
118    {
119	if let Self::Loud(this) = self {
120	    this.get_progress()
121	} else {
122	    0.0
123	}
124    }
125}
126
127impl<T> Spinner for MaybeSilent<T>
128    where T: Spinner
129{
130    fn bump(&mut self)
131    {
132	if let Self::Loud(this) = self {
133	    this.bump()
134	}
135    }
136}
137
138/// A trait for creating a progress bar or spinner with a title.
139impl<T> WithTitle for MaybeSilent<T>
140    where T: WithTitle
141{
142    #[inline] 
143    fn add_title(&mut self, string: impl AsRef<str>) {
144	if let Self::Loud(this) = self {
145	    this.add_title(string);
146	}
147    }
148    #[inline] 
149    fn with_title(self, string: impl AsRef<str>) -> Self
150    {
151	match self {
152	    Self::Loud(l) => Self::Loud(T::with_title(l, string)),
153	    n => n,
154	}
155    }
156    #[inline] 
157    fn update(&mut self)
158    {
159	if let Self::Loud(this) = self {
160	    this.update()
161	}
162    }
163    #[inline] 
164    fn complete(self)
165    {
166	if let Self::Loud(this) = self {
167	    this.complete()
168	}
169    }
170}
171
172impl<T> From<Option<T>> for MaybeSilent<T>
173{
174    #[inline] fn from(from: Option<T>) -> Self
175    {
176	match from {
177	    Some(from) => Self::Loud(from),
178	    None => Self::Silent,
179	}
180    }
181}
182
183impl<T> From<MaybeSilent<T>> for Option<T>
184{
185    fn from(from: MaybeSilent<T>) -> Self
186    {
187	match from {
188	    MaybeSilent::Loud(loud) => Some(loud),
189	    _ => None,
190	}
191    }
192}
193
194/// Return a `MaybeSilent` that is always silent
195#[cfg(nightly)]
196pub const fn always() -> MaybeSilent<!>
197{
198    MaybeSilent::Silent
199}
200
201/// Return a `MaybeSilent` that is always silent
202#[cfg(not(nightly))]
203pub const fn always() -> MaybeSilent<Silent>
204{
205    MaybeSilent::Silent
206}
207
208impl<T> MaybeSilent<T>
209{
210    /// Is this the not silent variant?
211    #[inline] pub fn is_loud(&self) -> bool
212    {
213	!self.is_silent()
214    }
215    /// Is this the silent variant?
216    #[inline] pub fn is_silent(&self) -> bool
217    {
218	if let Self::Silent = self {
219	    true
220	} else {
221	    false
222	}
223    }
224    /// Create a new `MaybeSilent` with a value.
225    pub const fn new_some(value: T) -> Self
226    {
227	Self::Loud(value)
228    }
229
230    /// Create a new `MaybeSilent` with a potential value
231    #[inline] pub fn new<U>(from: U) -> Self
232    where U: Into<Option<T>>
233    {
234	match from.into() {
235	    Some(x) => Self::Loud(x),
236	    _ => Self::Silent,
237	}
238    }
239    
240    /// Get a reference to the inner type if possible
241    pub fn as_ref(&self) -> Option<&T>
242    {
243	match self {
244	    Self::Loud(loud) => Some(loud),
245	    _ => None
246	}
247    }
248    /// Get a mutable reference to the inner type if possible
249    pub fn as_mut(&mut self) -> Option<&mut T>
250    {
251	match self {
252	    Self::Loud(loud) => Some(loud),
253	    _ => None
254	}
255    }
256
257    
258    /// Get a dynamic mutable reference to the internal value if it is `Display`.
259    pub fn as_display_mut(&mut self) -> Option<&mut (dyn Display + 'static)>
260    where T: Display + 'static
261    {
262	match self {
263	    Self::Loud(loud) => Some(loud),
264	    _ => None
265	}
266    }
267
268    /// Consume this instance and return the inner value if possible
269    #[inline] pub fn into_inner(self) -> Option<T>
270    {
271	self.into()
272    }
273
274    /// Consume this instance and return silent if it had no value
275    #[inline] pub fn into_silent(self) -> Option<Silent>
276    {
277	match self {
278	    Self::Silent => Some(Silent),
279	    _ => None
280	}
281    }
282    
283    /// Get a dynamic mutable reference to the internal value if it is `ProgressBar`
284    pub fn as_bar_mut(&mut self) -> Option<&mut (dyn ProgressBar + 'static)>
285    where T: ProgressBar + 'static
286    {
287	match self {
288	    Self::Loud(loud) => Some(loud),
289	    _ => None
290	}
291    }
292    
293    /// Get a dynamic mutable reference to the internal value if it is `Spinner`.
294    pub fn as_spinner_mut(&mut self) -> Option<&mut (dyn Spinner + 'static)>
295    where T: Spinner + 'static
296    {
297	match self {
298	    Self::Loud(loud) => Some(loud),
299	    _ => None
300	}
301    }
302
303    /// Get a dynamic reference to the internal value if it is `Display`.
304    pub fn as_display(&self) -> Option<&(dyn Display + 'static)>
305    where T: Display + 'static
306    {
307	match self {
308	    Self::Loud(loud) => Some(loud),
309	    _ => None
310	}
311    }
312    
313    /// Get a dynamic reference to the internal value if it is `ProgressBar`
314    pub fn as_bar(&self) -> Option<&(dyn ProgressBar + 'static)>
315    where T: ProgressBar + 'static
316    {
317	match self {
318	    Self::Loud(loud) => Some(loud),
319	    _ => None
320	}
321    }
322    
323    /// Get a dynamic reference to the internal value if it is `Spinner`.
324    pub fn as_spinner(&self) -> Option<&(dyn Spinner + 'static)>
325    where T: Spinner + 'static
326    {
327	match self {
328	    Self::Loud(loud) => Some(loud),
329	    _ => None
330	}
331    }
332}