render_tree/stylesheet/
accumulator.rs1use log::*;
2use std::io;
3use std::io::prelude::*;
4use termcolor::ColorSpec;
5use termcolor::WriteColor;
6
7pub struct ColorAccumulator {
37 buf: Vec<u8>,
38 color: ColorSpec,
39}
40
41impl ColorAccumulator {
42 pub fn new() -> ColorAccumulator {
43 ColorAccumulator {
44 buf: Vec::new(),
45 color: ColorSpec::new(),
46 }
47 }
48
49 pub fn to_string(self) -> String {
50 String::from_utf8(self.buf).unwrap()
51 }
52}
53
54impl io::Write for ColorAccumulator {
55 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
56 self.buf.extend(buf);
57 Ok(buf.len())
58 }
59
60 fn flush(&mut self) -> io::Result<()> {
61 Ok(())
62 }
63}
64
65impl WriteColor for ColorAccumulator {
66 fn supports_color(&self) -> bool {
67 true
68 }
69
70 fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
71 #![allow(unused_assignments)]
72
73 if self.color == *spec {
74 return Ok(());
75 } else {
76 trace!(
77 "eq={:?} spec={:?} current={:?}",
78 self.color == *spec,
79 spec,
80 self.color
81 );
82
83 self.color = spec.clone();
84 }
85
86 if spec.is_none() {
87 write!(self, "{{/}}")?;
88 return Ok(());
89 } else {
90 write!(self, "{{")?;
91 }
92
93 let mut first = true;
94
95 fn write_first(first: bool, write: &mut ColorAccumulator) -> io::Result<bool> {
96 if !first {
97 write!(write, " ")?;
98 }
99
100 Ok(false)
101 };
102
103 if let Some(fg) = spec.fg() {
104 first = write_first(first, self)?;
105 write!(self, "fg:{:?}", fg)?;
106 }
107
108 if let Some(bg) = spec.bg() {
109 first = write_first(first, self)?;
110 write!(self, "bg:{:?}", bg)?;
111 }
112
113 if spec.bold() {
114 first = write_first(first, self)?;
115 write!(self, "bold")?;
116 }
117
118 if spec.underline() {
119 first = write_first(first, self)?;
120 write!(self, "underline")?;
121 }
122
123 if spec.intense() {
124 first = write_first(first, self)?;
125 write!(self, "bright")?;
126 }
127
128 write!(self, "}}")?;
129
130 Ok(())
131 }
132
133 fn reset(&mut self) -> io::Result<()> {
134 let color = self.color.clone();
135
136 if color != ColorSpec::new() {
137 write!(self, "{{/}}")?;
138 self.color = ColorSpec::new();
139 }
140
141 Ok(())
142 }
143}