summaryrefslogtreecommitdiffstats
path: root/src/segment.rs
blob: a56e1bf82dc0fab2aba5427f1c2751f33171b0f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use ansi_term::Style;

#[derive(Clone)]
pub struct Segment {
    name: Option<String>,
    style: Style,
    value: String,
    prefix: BoxedSegment,
    suffix: BoxedSegment,
}

impl Segment {
    /// Creates a new segment with default fields
    pub fn new<T>(name: T) -> Segment
    where
        T: Into<String>,
        T: Copy,
    {
        let default_prefix = Some(Box::new(Segment {
            name: Some(format!("{} {}", name.into(), "prefix")),
            style: Style::default(),
            value: String::from("via "),
            prefix: None,
            suffix: None,
        }));

        let default_suffix = Some(Box::new(Segment {
            name: Some(format!("{} {}", name.into(), "suffix")),
            style: Style::default(),
            value: String::from(" "),
            prefix: None,
            suffix: None,
        }));

        Segment {
            name: Some(name.into()),
            style: Style::default(),
            value: String::from(""),
            prefix: default_prefix,
            suffix: default_suffix,
        }
    }

    /// Sets the style of the segment
    ///
    /// Accepts either `Color` or `Style`.
    pub fn set_style<T>(&mut self, style: T) -> &mut Segment
    where
        T: Into<Style>,
    {
        self.style = style.into();
        self
    }

    /// Sets the value of the segment
    pub fn set_value<T>(&mut self, value: T) -> &mut Segment
    where
        T: Into<String>,
    {
        self.value = value.into();
        self
    }

    /// Sets the prefix of the segment
    pub fn set_prefix(&mut self, prefix: BoxedSegment) -> &mut Segment {
        self.prefix = prefix;
        self
    }

    /// Sets the suffix of the segment
    pub fn set_suffix(&mut self, suffix: BoxedSegment) -> &mut Segment {
        self.suffix = suffix;
        self
    }

    /// Create a string with the formatted contents of a segment
    ///
    /// Will recursively also format the prefix and suffix of the segment being
    /// stringified.
    pub fn output(&self) -> String {
        let Segment {
            name: _name,
            prefix,
            value,
            style,
            suffix,
        } = self;

        let mut segment_string = String::new();

        // Skip the prefix for the first segment
        if let Some(prefix) = prefix {
            segment_string += &prefix.output()
        }

        segment_string += &style.paint(value).to_string();

        if let Some(suffix) = suffix {
            segment_string += &suffix.output();
        }

        segment_string
    }

    /// Create a string with the formatted contents of a segment while skipping the first segment.
    ///
    /// Will recursively also format the prefix and suffix of the segment being
    /// stringified.
    pub fn output_index(&self, index: usize) -> String {
        let Segment {
            name: _name,
            prefix,
            value,
            style,
            suffix,
        } = self;

        let mut segment_string = String::new();

        // Skip the prefix for the first segment
        if index != 0 {
            if let Some(prefix) = prefix {
                segment_string += &prefix.output_index(index)
            }
        }

        segment_string += &style.paint(value).to_string();

        if let Some(suffix) = suffix {
            segment_string += &suffix.output();
        }

        segment_string
    }
}

type BoxedSegment = Option<Box<Segment>>;