veloren_server_cli/
tuilog.rs1use ratatui::{
2 prelude::Line,
3 style::{Color, Modifier, Style},
4 text::{Span, Text},
5};
6use std::{
7 io::{self, Write},
8 sync::{Arc, Mutex},
9};
10use tracing::warn;
11
12#[derive(Debug, Default, Clone)]
13pub struct TuiLog<'a> {
14 pub inner: Arc<Mutex<Text<'a>>>,
15}
16
17impl TuiLog<'_> {
18 pub fn resize(&self, h: usize) {
19 let mut inner = self.inner.lock().unwrap();
20
21 let len = inner.lines.len().saturating_sub(h);
22 inner.lines.drain(..len);
23 }
24}
25
26impl Write for TuiLog<'_> {
27 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
28 use cansi::v3::categorise_text;
36
37 let line =
38 core::str::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
39
40 let mut spans = Vec::new();
41 let mut lines = Vec::new();
42
43 for out in categorise_text(line) {
44 let mut style = Style::default();
45 style.fg = match out.fg {
48 Some(cansi::Color::Black) => Some(Color::Black),
49 Some(cansi::Color::Red) => Some(Color::Red),
50 Some(cansi::Color::Green) => Some(Color::Green),
51 Some(cansi::Color::Yellow) => Some(Color::Yellow),
52 Some(cansi::Color::Blue) => Some(Color::Blue),
53 Some(cansi::Color::Magenta) => Some(Color::Magenta),
54 Some(cansi::Color::Cyan) => Some(Color::Cyan),
55 Some(cansi::Color::White) => Some(Color::White),
56 Some(c) => {
58 warn!("Unknown color {:#?}", c);
59 style.fg
60 },
61 None => style.fg,
62 };
63 match out.intensity {
64 Some(cansi::Intensity::Normal) | None => {},
65 Some(cansi::Intensity::Bold) => style.add_modifier = Modifier::BOLD,
66 Some(cansi::Intensity::Faint) => style.add_modifier = Modifier::DIM,
67 }
68
69 for t in out.text.split_inclusive('\n') {
71 if !t.is_empty() {
72 spans.push(Span::styled(t.to_owned(), style));
73 }
74 if t.ends_with('\n') {
75 lines.push(Line::from(core::mem::take(&mut spans)));
76 }
77 }
78 }
79 if !spans.is_empty() {
80 lines.push(Line::from(spans));
81 }
82
83 self.inner.lock().unwrap().lines.append(&mut lines);
84
85 Ok(buf.len())
86 }
87
88 fn flush(&mut self) -> io::Result<()> { Ok(()) }
90}