From edacaf7ff4e4b14702f6361af5a6da713b7dc564 Mon Sep 17 00:00:00 2001 From: Linda_pp Date: Sun, 12 Nov 2023 14:43:51 +0900 Subject: [PATCH] feat(buffer): deprecate `Cell::symbol` field (#624) The Cell::symbol field is now accessible via a getter method (`symbol()`). This will allow us to make future changes to the Cell internals such as replacing `String` with `compact_str`. --- src/backend/crossterm.rs | 2 +- src/backend/termion.rs | 2 +- src/backend/termwiz.rs | 2 +- src/backend/test.rs | 6 +++--- src/buffer.rs | 36 +++++++++++++++++++++++++++++------- src/widgets/canvas/line.rs | 2 +- tests/terminal.rs | 8 ++++---- 7 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/backend/crossterm.rs b/src/backend/crossterm.rs index 77372229..de9c9152 100644 --- a/src/backend/crossterm.rs +++ b/src/backend/crossterm.rs @@ -161,7 +161,7 @@ where underline_color = cell.underline_color; } - queue!(self.writer, Print(&cell.symbol))?; + queue!(self.writer, Print(cell.symbol()))?; } #[cfg(feature = "underline-color")] diff --git a/src/backend/termion.rs b/src/backend/termion.rs index 0006c7a5..3fa5d4b6 100644 --- a/src/backend/termion.rs +++ b/src/backend/termion.rs @@ -179,7 +179,7 @@ where write!(string, "{}", Bg(cell.bg)).unwrap(); bg = cell.bg; } - string.push_str(&cell.symbol); + string.push_str(cell.symbol()); } write!( self.writer, diff --git a/src/backend/termwiz.rs b/src/backend/termwiz.rs index d3e22fc1..001f6bad 100644 --- a/src/backend/termwiz.rs +++ b/src/backend/termwiz.rs @@ -176,7 +176,7 @@ impl Backend for TermwizBackend { }, ))); - self.buffered_terminal.add_change(&cell.symbol); + self.buffered_terminal.add_change(cell.symbol()); } Ok(()) } diff --git a/src/backend/test.rs b/src/backend/test.rs index 39199127..310978f5 100644 --- a/src/backend/test.rs +++ b/src/backend/test.rs @@ -56,11 +56,11 @@ fn buffer_view(buffer: &Buffer) -> String { view.push('"'); for (x, c) in cells.iter().enumerate() { if skip == 0 { - view.push_str(&c.symbol); + view.push_str(c.symbol()); } else { - overwritten.push((x, &c.symbol)); + overwritten.push((x, c.symbol())); } - skip = std::cmp::max(skip, c.symbol.width()).saturating_sub(1); + skip = std::cmp::max(skip, c.symbol().width()).saturating_sub(1); } view.push('"'); if !overwritten.is_empty() { diff --git a/src/buffer.rs b/src/buffer.rs index b87881b5..495c7dcd 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -16,6 +16,12 @@ use crate::{ #[derive(Debug, Clone, Eq, PartialEq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Cell { + #[deprecated( + since = "0.24.1", + note = "This field will be hidden at next major version. Use `Cell::symbol` method to get \ + the value. Use `Cell::set_symbol` to update the field. Use `Cell::default` to \ + create `Cell` instance" + )] pub symbol: String, pub fg: Color, pub bg: Color, @@ -25,7 +31,12 @@ pub struct Cell { pub skip: bool, } +#[allow(deprecated)] // For Cell::symbol impl Cell { + pub fn symbol(&self) -> &str { + self.symbol.as_str() + } + pub fn set_symbol(&mut self, symbol: &str) -> &mut Cell { self.symbol.clear(); self.symbol.push_str(symbol); @@ -106,6 +117,7 @@ impl Cell { impl Default for Cell { fn default() -> Cell { + #[allow(deprecated)] // For Cell::symbol Cell { symbol: " ".into(), fg: Color::Reset, @@ -132,7 +144,7 @@ impl Default for Cell { /// /// let mut buf = Buffer::empty(Rect{x: 0, y: 0, width: 10, height: 5}); /// buf.get_mut(0, 2).set_symbol("x"); -/// assert_eq!(buf.get(0, 2).symbol, "x"); +/// assert_eq!(buf.get(0, 2).symbol(), "x"); /// buf.set_string(3, 0, "string", Style::default().fg(Color::Red).bg(Color::White)); /// assert_eq!(buf.get(5, 0), &Cell{ /// symbol: String::from("r"), @@ -144,7 +156,7 @@ impl Default for Cell { /// skip: false /// }); /// buf.get_mut(5, 0).set_char('x'); -/// assert_eq!(buf.get(5, 0).symbol, "x"); +/// assert_eq!(buf.get(5, 0).symbol(), "x"); /// ``` #[derive(Default, Clone, Eq, PartialEq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -471,9 +483,9 @@ impl Buffer { updates.push((x, y, &next_buffer[i])); } - to_skip = current.symbol.width().saturating_sub(1); + to_skip = current.symbol().width().saturating_sub(1); - let affected_width = std::cmp::max(current.symbol.width(), previous.symbol.width()); + let affected_width = std::cmp::max(current.symbol().width(), previous.symbol().width()); invalidated = std::cmp::max(affected_width, invalidated).saturating_sub(1); } updates @@ -555,11 +567,11 @@ impl Debug for Buffer { f.write_str(" \"")?; for (x, c) in line.iter().enumerate() { if skip == 0 { - f.write_str(&c.symbol)?; + f.write_str(c.symbol())?; } else { - overwritten.push((x, &c.symbol)); + overwritten.push((x, c.symbol())); } - skip = std::cmp::max(skip, c.symbol.width()).saturating_sub(1); + skip = std::cmp::max(skip, c.symbol().width()).saturating_sub(1); #[cfg(feature = "underline-color")] { let style = (c.fg, c.bg, c.underline_color, c.modifier); @@ -1043,4 +1055,14 @@ mod tests { buf.set_string(0, 1, "bar", Style::new().blue()); assert_eq!(buf, Buffer::with_lines(vec!["foo".red(), "bar".blue()])); } + + #[test] + fn cell_symbol_field() { + let mut cell = Cell::default(); + assert_eq!(cell.symbol(), " "); + cell.set_symbol("ใ‚"); // Multi-byte character + assert_eq!(cell.symbol(), "ใ‚"); + cell.set_symbol("๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ"); // Multiple code units combined with ZWJ + assert_eq!(cell.symbol(), "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ"); + } } diff --git a/src/widgets/canvas/line.rs b/src/widgets/canvas/line.rs index 8463cb95..a3542b96 100644 --- a/src/widgets/canvas/line.rs +++ b/src/widgets/canvas/line.rs @@ -128,7 +128,7 @@ mod tests { let mut expected = Buffer::with_lines(expected_lines); for cell in expected.content.iter_mut() { - if cell.symbol == "โ€ข" { + if cell.symbol() == "โ€ข" { cell.set_style(Style::new().red()); } } diff --git a/tests/terminal.rs b/tests/terminal.rs index 6e7594d3..9d9378f9 100644 --- a/tests/terminal.rs +++ b/tests/terminal.rs @@ -25,9 +25,9 @@ fn swap_buffer_clears_prev_buffer() { terminal .current_buffer_mut() .set_string(0, 0, "Hello", ratatui::style::Style::reset()); - assert_eq!(terminal.current_buffer_mut().content()[0].symbol, "H"); + assert_eq!(terminal.current_buffer_mut().content()[0].symbol(), "H"); terminal.swap_buffers(); - assert_eq!(terminal.current_buffer_mut().content()[0].symbol, " "); + assert_eq!(terminal.current_buffer_mut().content()[0].symbol(), " "); } #[test] @@ -38,14 +38,14 @@ fn terminal_draw_returns_the_completed_frame() -> Result<(), Box> { let paragraph = Paragraph::new("Test"); f.render_widget(paragraph, f.size()); })?; - assert_eq!(frame.buffer.get(0, 0).symbol, "T"); + assert_eq!(frame.buffer.get(0, 0).symbol(), "T"); assert_eq!(frame.area, Rect::new(0, 0, 10, 10)); terminal.backend_mut().resize(8, 8); let frame = terminal.draw(|f| { let paragraph = Paragraph::new("test"); f.render_widget(paragraph, f.size()); })?; - assert_eq!(frame.buffer.get(0, 0).symbol, "t"); + assert_eq!(frame.buffer.get(0, 0).symbol(), "t"); assert_eq!(frame.area, Rect::new(0, 0, 8, 8)); Ok(()) }