oxide_update_engine_display/
line_display.rs1use crate::line_display_shared::{
6 LineDisplayFormatter, LineDisplayOutput, LineDisplayShared,
7};
8use chrono::{DateTime, Utc};
9use debug_ignore::DebugIgnore;
10use derive_where::derive_where;
11use owo_colors::Style;
12use oxide_update_engine_types::{
13 buffer::{EventBuffer, ExecutionTerminalInfo},
14 spec::EngineSpec,
15};
16use std::time::Duration;
17
18#[derive_where(Debug)]
22pub struct LineDisplay<W> {
23 writer: DebugIgnore<W>,
24 shared: LineDisplayShared,
25 formatter: LineDisplayFormatter,
26 prefix: String,
27}
28
29impl<W: std::io::Write> LineDisplay<W> {
30 pub fn new(writer: W) -> Self {
32 Self {
33 writer: DebugIgnore(writer),
34 shared: LineDisplayShared::default(),
35 formatter: LineDisplayFormatter::new(),
36 prefix: String::new(),
37 }
38 }
39
40 #[inline]
42 pub fn set_prefix(&mut self, prefix: impl Into<String>) {
43 self.prefix = prefix.into();
44 }
45
46 #[inline]
48 pub fn set_styles(&mut self, styles: LineDisplayStyles) {
49 self.formatter.set_styles(styles);
50 }
51
52 #[inline]
58 pub fn set_start_time(&mut self, start_time: DateTime<Utc>) {
59 self.shared.set_start_time(start_time);
60 }
61
62 #[inline]
64 pub fn set_progress_interval(&mut self, interval: Duration) {
65 self.formatter.set_progress_interval(interval);
66 }
67
68 pub fn write_event_buffer<S: EngineSpec>(
73 &mut self,
74 buffer: &EventBuffer<S>,
75 ) -> std::io::Result<()> {
76 let mut out = LineDisplayOutput::new();
77 self.shared
78 .with_context(&self.prefix, &self.formatter)
79 .format_event_buffer(buffer, &mut out);
80 for line in out.iter() {
81 writeln!(self.writer, "{line}")?;
82 }
83
84 Ok(())
85 }
86
87 pub fn write_terminal_info(
89 &mut self,
90 info: &ExecutionTerminalInfo,
91 ) -> std::io::Result<()> {
92 let line = self
93 .shared
94 .with_context(&self.prefix, &self.formatter)
95 .format_terminal_info(info);
96 writeln!(self.writer, "{line}")
97 }
98
99 pub fn write_generic(&mut self, message: &str) -> std::io::Result<()> {
101 let line = self
102 .shared
103 .with_context(&self.prefix, &self.formatter)
104 .format_generic(message);
105 writeln!(self.writer, "{line}")
106 }
107}
108
109#[derive(Debug, Default)]
113#[non_exhaustive]
114pub struct LineDisplayStyles {
115 pub prefix_style: Style,
116 pub meta_style: Style,
117 pub step_name_style: Style,
118 pub progress_style: Style,
119 pub progress_message_style: Style,
120 pub warning_style: Style,
121 pub warning_message_style: Style,
122 pub error_style: Style,
123 pub error_message_style: Style,
124 pub skipped_style: Style,
125 pub retry_style: Style,
126}
127
128impl LineDisplayStyles {
129 pub fn colorized() -> Self {
131 Self {
132 prefix_style: Style::new().bold(),
133 meta_style: Style::new().bold(),
134 step_name_style: Style::new().cyan(),
135 progress_style: Style::new().bold().green(),
136 progress_message_style: Style::new().green(),
137 warning_style: Style::new().bold().yellow(),
138 warning_message_style: Style::new().yellow(),
139 error_style: Style::new().bold().red(),
140 error_message_style: Style::new().red(),
141 skipped_style: Style::new().bold().yellow(),
142 retry_style: Style::new().bold().yellow(),
143 }
144 }
145}