livesplit_core/timing/formatter/
none_wrapper.rs

1//! The none_wrapper modules provides wrapper types for Time Formatters that
2//! allows you to create a new Time Formatter by wrapping another one and
3//! changing its behavior when formatting empty times.
4
5use super::{TimeFormatter, DASH};
6use crate::TimeSpan;
7use core::fmt::{Display, Formatter, Result};
8
9/// A Time Span to be formatted by a None Wrapper.
10pub struct Inner<'a, F, S> {
11    time: Option<TimeSpan>,
12    wrapper: &'a NoneWrapper<F, S>,
13}
14
15/// A None Wrapper wraps a Time Formatter and changes its behavior when
16/// formatting an empty time. The None Wrapper in particular replaces the empty
17/// time with any string provided to the None Wrapper.
18pub struct NoneWrapper<F, S>(F, S);
19
20/// The Dash Wrapper is a helper type for creating a None Wrapper that always
21/// uses a dash for the empty times.
22pub struct DashWrapper;
23
24/// The Empty Wrapper is a helper type for creating a None Wrapper that always
25/// uses an empty string for the empty times.
26pub struct EmptyWrapper;
27
28impl<'a, F: 'a + TimeFormatter<'a>, S: AsRef<str>> NoneWrapper<F, S> {
29    /// Creates a new None Wrapper that wraps around the Time Formatter provided
30    /// and replaces its empty time formatting by the string provided to this
31    /// Wrapper.
32    pub const fn new(inner: F, none_text: S) -> Self {
33        NoneWrapper(inner, none_text)
34    }
35}
36
37impl DashWrapper {
38    /// Creates a new Dash Wrapper.
39    pub const fn new<'a, F: 'a + TimeFormatter<'a>>(inner: F) -> NoneWrapper<F, &'static str> {
40        NoneWrapper::new(inner, DASH)
41    }
42}
43
44impl EmptyWrapper {
45    /// Creates a new Empty Wrapper.
46    pub const fn new<'a, F: 'a + TimeFormatter<'a>>(inner: F) -> NoneWrapper<F, &'static str> {
47        NoneWrapper::new(inner, "")
48    }
49}
50
51impl<'a, F: 'a + TimeFormatter<'a>, S: 'a + AsRef<str>> TimeFormatter<'a> for NoneWrapper<F, S> {
52    type Inner = Inner<'a, F, S>;
53
54    fn format<T>(&'a self, time: T) -> Self::Inner
55    where
56        T: Into<Option<TimeSpan>>,
57    {
58        Inner {
59            time: time.into(),
60            wrapper: self,
61        }
62    }
63}
64
65impl<'a, F: TimeFormatter<'a>, S: 'a + AsRef<str>> Display for Inner<'a, F, S> {
66    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
67        if self.time.is_none() {
68            self.wrapper.1.as_ref().fmt(f)
69        } else {
70            self.wrapper.0.format(self.time).fmt(f)
71        }
72    }
73}