From ebe10cd81fc7392d26e6b93ae8d512175404f7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jagoda=20Estera=20=C5=9Al=C4=85zak?= <128227338+j-g00da@users.noreply.github.com> Date: Fri, 4 Apr 2025 05:02:54 +0200 Subject: [PATCH] feat(no_std): remove redundant `std` usages in `ratatui-core` (#1753) Resolves https://github.com/ratatui/ratatui/issues/1751 --- Cargo.lock | 1 + ratatui-core/Cargo.toml | 1 + ratatui-core/src/backend.rs | 10 +++------- ratatui-core/src/backend/test.rs | 19 ++++++++---------- ratatui-core/src/buffer/buffer.rs | 12 +++++------ ratatui-core/src/layout/constraint.rs | 2 +- ratatui-core/src/layout/layout.rs | 12 +++++------ ratatui-core/src/layout/margin.rs | 2 +- ratatui-core/src/layout/position.rs | 2 +- ratatui-core/src/layout/rect.rs | 4 ++-- ratatui-core/src/layout/size.rs | 2 +- ratatui-core/src/lib.rs | 2 ++ ratatui-core/src/style.rs | 2 +- ratatui-core/src/style/color.rs | 8 ++++---- ratatui-core/src/style/stylize.rs | 2 +- ratatui-core/src/terminal/viewport.rs | 2 +- ratatui-core/src/text/line.rs | 22 ++++++++++----------- ratatui-core/src/text/masked.rs | 4 ++-- ratatui-core/src/text/span.rs | 6 +++--- ratatui-core/src/text/text.rs | 22 ++++++++++----------- ratatui-core/src/widgets/stateful_widget.rs | 2 +- 21 files changed, 68 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 198d20dc..3ed8f262 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2551,6 +2551,7 @@ dependencies = [ "cassowary", "compact_str", "document-features", + "hashbrown", "indoc", "itertools 0.13.0", "lru", diff --git a/ratatui-core/Cargo.toml b/ratatui-core/Cargo.toml index 5d520622..9b92bfc8 100644 --- a/ratatui-core/Cargo.toml +++ b/ratatui-core/Cargo.toml @@ -48,6 +48,7 @@ bitflags = "2.3" cassowary = "0.3" compact_str = "0.8.0" document-features = { workspace = true, optional = true } +hashbrown = "0.15.2" indoc.workspace = true itertools.workspace = true lru = "0.12.0" diff --git a/ratatui-core/src/backend.rs b/ratatui-core/src/backend.rs index 871781e4..c83d2947 100644 --- a/ratatui-core/src/backend.rs +++ b/ratatui-core/src/backend.rs @@ -100,6 +100,7 @@ //! [Examples]: https://github.com/ratatui/ratatui/tree/main/ratatui/examples/README.md //! [Backend Comparison]: https://ratatui.rs/concepts/backends/comparison/ //! [Ratatui Website]: https://ratatui.rs +use core::ops; use std::io; use strum::{Display, EnumString}; @@ -341,8 +342,7 @@ pub trait Backend { /// For examples of how this function is expected to work, refer to the tests for /// [`TestBackend::scroll_region_up`]. #[cfg(feature = "scrolling-regions")] - fn scroll_region_up(&mut self, region: std::ops::Range, line_count: u16) - -> io::Result<()>; + fn scroll_region_up(&mut self, region: ops::Range, line_count: u16) -> io::Result<()>; /// Scroll a region of the screen downwards, where a region is specified by a (half-open) range /// of rows. @@ -363,11 +363,7 @@ pub trait Backend { /// For examples of how this function is expected to work, refer to the tests for /// [`TestBackend::scroll_region_down`]. #[cfg(feature = "scrolling-regions")] - fn scroll_region_down( - &mut self, - region: std::ops::Range, - line_count: u16, - ) -> io::Result<()>; + fn scroll_region_down(&mut self, region: ops::Range, line_count: u16) -> io::Result<()>; } #[cfg(test)] diff --git a/ratatui-core/src/backend/test.rs b/ratatui-core/src/backend/test.rs index 54fb0125..0a0c4f2e 100644 --- a/ratatui-core/src/backend/test.rs +++ b/ratatui-core/src/backend/test.rs @@ -1,8 +1,9 @@ //! This module provides the `TestBackend` implementation for the [`Backend`] trait. //! It is used in the integration tests to verify the correctness of the library. -use std::fmt::{self, Write}; -use std::{io, iter}; +use core::fmt::{self, Write}; +use core::{iter, ops}; +use std::io; use unicode_width::UnicodeWidthStr; @@ -54,7 +55,7 @@ fn buffer_view(buffer: &Buffer) -> String { } else { overwritten.push((x, c.symbol())); } - skip = std::cmp::max(skip, c.symbol().width()).saturating_sub(1); + skip = core::cmp::max(skip, c.symbol().width()).saturating_sub(1); } view.push('"'); if !overwritten.is_empty() { @@ -363,7 +364,7 @@ impl Backend for TestBackend { } #[cfg(feature = "scrolling-regions")] - fn scroll_region_up(&mut self, region: std::ops::Range, scroll_by: u16) -> io::Result<()> { + fn scroll_region_up(&mut self, region: ops::Range, scroll_by: u16) -> io::Result<()> { let width: usize = self.buffer.area.width.into(); let cell_region_start = width * region.start.min(self.buffer.area.height) as usize; let cell_region_end = width * region.end.min(self.buffer.area.height) as usize; @@ -409,11 +410,7 @@ impl Backend for TestBackend { } #[cfg(feature = "scrolling-regions")] - fn scroll_region_down( - &mut self, - region: std::ops::Range, - scroll_by: u16, - ) -> io::Result<()> { + fn scroll_region_down(&mut self, region: ops::Range, scroll_by: u16) -> io::Result<()> { let width: usize = self.buffer.area.width.into(); let cell_region_start = width * region.start.min(self.buffer.area.height) as usize; let cell_region_end = width * region.end.min(self.buffer.area.height) as usize; @@ -1026,7 +1023,7 @@ mod tests { #[case([A, B, C, D, E], 2..2, 2, [], [A, B, C, D, E])] fn scroll_region_up( #[case] initial_screen: [&'static str; L], - #[case] range: std::ops::Range, + #[case] range: ops::Range, #[case] scroll_by: u16, #[case] expected_scrollback: [&'static str; M], #[case] expected_buffer: [&'static str; N], @@ -1060,7 +1057,7 @@ mod tests { #[case([A, B, C, D, E], 2..2, 2, [A, B, C, D, E])] fn scroll_region_down( #[case] initial_screen: [&'static str; M], - #[case] range: std::ops::Range, + #[case] range: ops::Range, #[case] scroll_by: u16, #[case] expected_buffer: [&'static str; N], ) { diff --git a/ratatui-core/src/buffer/buffer.rs b/ratatui-core/src/buffer/buffer.rs index e9723805..baed6cf9 100644 --- a/ratatui-core/src/buffer/buffer.rs +++ b/ratatui-core/src/buffer/buffer.rs @@ -1,5 +1,5 @@ -use std::fmt; -use std::ops::{Index, IndexMut}; +use core::ops::{Index, IndexMut}; +use core::{cmp, fmt}; use unicode_segmentation::UnicodeSegmentation; use unicode_width::UnicodeWidthStr; @@ -499,8 +499,8 @@ impl Buffer { to_skip = current.symbol().width().saturating_sub(1); - let affected_width = std::cmp::max(current.symbol().width(), previous.symbol().width()); - invalidated = std::cmp::max(affected_width, invalidated).saturating_sub(1); + let affected_width = cmp::max(current.symbol().width(), previous.symbol().width()); + invalidated = cmp::max(affected_width, invalidated).saturating_sub(1); } updates } @@ -592,7 +592,7 @@ impl fmt::Debug for Buffer { } else { overwritten.push((x, c.symbol())); } - skip = std::cmp::max(skip, c.symbol().width()).saturating_sub(1); + skip = cmp::max(skip, c.symbol().width()).saturating_sub(1); #[cfg(feature = "underline-color")] { let style = (c.fg, c.bg, c.underline_color, c.modifier); @@ -638,7 +638,7 @@ impl fmt::Debug for Buffer { #[cfg(test)] mod tests { - use std::iter; + use core::iter; use itertools::Itertools; use rstest::{fixture, rstest}; diff --git a/ratatui-core/src/layout/constraint.rs b/ratatui-core/src/layout/constraint.rs index c17dac73..14add10e 100644 --- a/ratatui-core/src/layout/constraint.rs +++ b/ratatui-core/src/layout/constraint.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; use strum::EnumIs; diff --git a/ratatui-core/src/layout/layout.rs b/ratatui-core/src/layout/layout.rs index edcef8cf..9e7588fc 100644 --- a/ratatui-core/src/layout/layout.rs +++ b/ratatui-core/src/layout/layout.rs @@ -1,12 +1,12 @@ -use std::cell::RefCell; -use std::collections::HashMap; -use std::iter; -use std::num::NonZeroUsize; -use std::rc::Rc; +use alloc::rc::Rc; +use core::cell::RefCell; +use core::iter; +use core::num::NonZeroUsize; use cassowary::strength::REQUIRED; use cassowary::WeightedRelation::{EQ, GE, LE}; use cassowary::{AddConstraintError, Expression, Solver, Variable}; +use hashbrown::HashMap; use itertools::Itertools; use lru::LruCache; @@ -1404,7 +1404,7 @@ mod tests { /// - underflow: constraint is for less than the full space /// - overflow: constraint is for more than the full space mod split { - use std::ops::Range; + use core::ops::Range; use itertools::Itertools; use pretty_assertions::assert_eq; diff --git a/ratatui-core/src/layout/margin.rs b/ratatui-core/src/layout/margin.rs index 7e96da13..cc60fd45 100644 --- a/ratatui-core/src/layout/margin.rs +++ b/ratatui-core/src/layout/margin.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/ratatui-core/src/layout/position.rs b/ratatui-core/src/layout/position.rs index bd327473..462ce941 100644 --- a/ratatui-core/src/layout/position.rs +++ b/ratatui-core/src/layout/position.rs @@ -1,5 +1,5 @@ #![warn(missing_docs)] -use std::fmt; +use core::fmt; use crate::layout::Rect; diff --git a/ratatui-core/src/layout/rect.rs b/ratatui-core/src/layout/rect.rs index ac061884..cb7d0664 100644 --- a/ratatui-core/src/layout/rect.rs +++ b/ratatui-core/src/layout/rect.rs @@ -1,6 +1,6 @@ #![warn(missing_docs)] -use std::cmp::{max, min}; -use std::fmt; +use core::cmp::{max, min}; +use core::fmt; use crate::layout::{Margin, Position, Size}; diff --git a/ratatui-core/src/layout/size.rs b/ratatui-core/src/layout/size.rs index 5c7a3c5c..776c7fbd 100644 --- a/ratatui-core/src/layout/size.rs +++ b/ratatui-core/src/layout/size.rs @@ -1,5 +1,5 @@ #![warn(missing_docs)] -use std::fmt; +use core::fmt; use crate::layout::Rect; diff --git a/ratatui-core/src/lib.rs b/ratatui-core/src/lib.rs index 7c9a60cc..b66582ea 100644 --- a/ratatui-core/src/lib.rs +++ b/ratatui-core/src/lib.rs @@ -38,6 +38,8 @@ //! //! This project is licensed under the MIT License. See the [LICENSE](../LICENSE) file for details. +extern crate alloc; + pub mod backend; pub mod buffer; pub mod layout; diff --git a/ratatui-core/src/style.rs b/ratatui-core/src/style.rs index 3b3a9b31..15450828 100644 --- a/ratatui-core/src/style.rs +++ b/ratatui-core/src/style.rs @@ -68,7 +68,7 @@ //! //! [`Span`]: crate::text::Span -use std::fmt; +use core::fmt; use bitflags::bitflags; pub use color::{Color, ParseColorError}; diff --git a/ratatui-core/src/style/color.rs b/ratatui-core/src/style/color.rs index 93846590..9a3709fe 100644 --- a/ratatui-core/src/style/color.rs +++ b/ratatui-core/src/style/color.rs @@ -1,7 +1,7 @@ #![allow(clippy::unreadable_literal)] -use std::fmt; -use std::str::FromStr; +use core::fmt; +use core::str::FromStr; use crate::style::stylize::{ColorDebug, ColorDebugKind}; @@ -249,7 +249,7 @@ impl fmt::Display for ParseColorError { } } -impl std::error::Error for ParseColorError {} +impl core::error::Error for ParseColorError {} /// Converts a string representation to a `Color` instance. /// @@ -505,7 +505,7 @@ impl From<(u8, u8, u8, u8)> for Color { #[cfg(test)] mod tests { - use std::error::Error; + use core::error::Error; #[cfg(feature = "palette")] use palette::{Hsl, Hsluv}; diff --git a/ratatui-core/src/style/stylize.rs b/ratatui-core/src/style/stylize.rs index a92a18e1..a9a695ef 100644 --- a/ratatui-core/src/style/stylize.rs +++ b/ratatui-core/src/style/stylize.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; use crate::style::{Color, Modifier, Style}; use crate::text::Span; diff --git a/ratatui-core/src/terminal/viewport.rs b/ratatui-core/src/terminal/viewport.rs index 2ae95aba..71307464 100644 --- a/ratatui-core/src/terminal/viewport.rs +++ b/ratatui-core/src/terminal/viewport.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; use crate::layout::Rect; diff --git a/ratatui-core/src/text/line.rs b/ratatui-core/src/text/line.rs index 48b121de..4e4b3ab4 100644 --- a/ratatui-core/src/text/line.rs +++ b/ratatui-core/src/text/line.rs @@ -1,7 +1,7 @@ #![deny(missing_docs)] #![warn(clippy::pedantic, clippy::nursery, clippy::arithmetic_side_effects)] -use std::borrow::Cow; -use std::fmt; +use alloc::borrow::Cow; +use core::fmt; use unicode_truncate::UnicodeTruncateStr; @@ -531,12 +531,12 @@ impl<'a> Line<'a> { } /// Returns an iterator over the spans of this line. - pub fn iter(&self) -> std::slice::Iter> { + pub fn iter(&self) -> core::slice::Iter> { self.spans.iter() } /// Returns a mutable iterator over the spans of this line. - pub fn iter_mut(&mut self) -> std::slice::IterMut> { + pub fn iter_mut(&mut self) -> core::slice::IterMut> { self.spans.iter_mut() } @@ -561,7 +561,7 @@ impl<'a> Line<'a> { impl<'a> IntoIterator for Line<'a> { type Item = Span<'a>; - type IntoIter = std::vec::IntoIter>; + type IntoIter = alloc::vec::IntoIter>; fn into_iter(self) -> Self::IntoIter { self.spans.into_iter() @@ -570,7 +570,7 @@ impl<'a> IntoIterator for Line<'a> { impl<'a> IntoIterator for &'a Line<'a> { type Item = &'a Span<'a>; - type IntoIter = std::slice::Iter<'a, Span<'a>>; + type IntoIter = core::slice::Iter<'a, Span<'a>>; fn into_iter(self) -> Self::IntoIter { self.iter() @@ -579,7 +579,7 @@ impl<'a> IntoIterator for &'a Line<'a> { impl<'a> IntoIterator for &'a mut Line<'a> { type Item = &'a mut Span<'a>; - type IntoIter = std::slice::IterMut<'a, Span<'a>>; + type IntoIter = core::slice::IterMut<'a, Span<'a>>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() @@ -638,7 +638,7 @@ where } /// Adds a `Span` to a `Line`, returning a new `Line` with the `Span` added. -impl<'a> std::ops::Add> for Line<'a> { +impl<'a> core::ops::Add> for Line<'a> { type Output = Self; fn add(mut self, rhs: Span<'a>) -> Self::Output { @@ -648,7 +648,7 @@ impl<'a> std::ops::Add> for Line<'a> { } /// Adds two `Line`s together, returning a new `Text` with the contents of the two `Line`s. -impl<'a> std::ops::Add for Line<'a> { +impl<'a> core::ops::Add for Line<'a> { type Output = Text<'a>; fn add(self, rhs: Self) -> Self::Output { @@ -656,7 +656,7 @@ impl<'a> std::ops::Add for Line<'a> { } } -impl<'a> std::ops::AddAssign> for Line<'a> { +impl<'a> core::ops::AddAssign> for Line<'a> { fn add_assign(&mut self, rhs: Span<'a>) { self.spans.push(rhs); } @@ -831,7 +831,7 @@ impl Styled for Line<'_> { #[cfg(test)] mod tests { - use std::iter; + use core::iter; use rstest::{fixture, rstest}; diff --git a/ratatui-core/src/text/masked.rs b/ratatui-core/src/text/masked.rs index 386aec92..4c9d4355 100644 --- a/ratatui-core/src/text/masked.rs +++ b/ratatui-core/src/text/masked.rs @@ -1,5 +1,5 @@ -use std::borrow::Cow; -use std::fmt; +use alloc::borrow::Cow; +use core::fmt; use crate::text::Text; diff --git a/ratatui-core/src/text/span.rs b/ratatui-core/src/text/span.rs index 07544261..dba6fe78 100644 --- a/ratatui-core/src/text/span.rs +++ b/ratatui-core/src/text/span.rs @@ -1,5 +1,5 @@ -use std::borrow::Cow; -use std::fmt; +use alloc::borrow::Cow; +use core::fmt; use unicode_segmentation::UnicodeSegmentation; use unicode_width::UnicodeWidthStr; @@ -384,7 +384,7 @@ where } } -impl<'a> std::ops::Add for Span<'a> { +impl<'a> core::ops::Add for Span<'a> { type Output = Line<'a>; fn add(self, rhs: Self) -> Self::Output { diff --git a/ratatui-core/src/text/text.rs b/ratatui-core/src/text/text.rs index ec6b1b1c..35cbc454 100644 --- a/ratatui-core/src/text/text.rs +++ b/ratatui-core/src/text/text.rs @@ -1,6 +1,6 @@ #![warn(missing_docs)] -use std::borrow::Cow; -use std::fmt; +use alloc::borrow::Cow; +use core::fmt; use crate::buffer::Buffer; use crate::layout::{Alignment, Rect}; @@ -504,12 +504,12 @@ impl<'a> Text<'a> { } /// Returns an iterator over the lines of the text. - pub fn iter(&self) -> std::slice::Iter> { + pub fn iter(&self) -> core::slice::Iter> { self.lines.iter() } /// Returns an iterator that allows modifying each line. - pub fn iter_mut(&mut self) -> std::slice::IterMut> { + pub fn iter_mut(&mut self) -> core::slice::IterMut> { self.lines.iter_mut() } @@ -558,7 +558,7 @@ impl<'a> Text<'a> { impl<'a> IntoIterator for Text<'a> { type Item = Line<'a>; - type IntoIter = std::vec::IntoIter; + type IntoIter = alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.lines.into_iter() @@ -567,7 +567,7 @@ impl<'a> IntoIterator for Text<'a> { impl<'a> IntoIterator for &'a Text<'a> { type Item = &'a Line<'a>; - type IntoIter = std::slice::Iter<'a, Line<'a>>; + type IntoIter = core::slice::Iter<'a, Line<'a>>; fn into_iter(self) -> Self::IntoIter { self.iter() @@ -576,7 +576,7 @@ impl<'a> IntoIterator for &'a Text<'a> { impl<'a> IntoIterator for &'a mut Text<'a> { type Item = &'a mut Line<'a>; - type IntoIter = std::slice::IterMut<'a, Line<'a>>; + type IntoIter = core::slice::IterMut<'a, Line<'a>>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() @@ -641,7 +641,7 @@ where } } -impl<'a> std::ops::Add> for Text<'a> { +impl<'a> core::ops::Add> for Text<'a> { type Output = Self; fn add(mut self, line: Line<'a>) -> Self::Output { @@ -653,7 +653,7 @@ impl<'a> std::ops::Add> for Text<'a> { /// Adds two `Text` together. /// /// This ignores the style and alignment of the second `Text`. -impl std::ops::Add for Text<'_> { +impl core::ops::Add for Text<'_> { type Output = Self; fn add(mut self, text: Self) -> Self::Output { @@ -662,7 +662,7 @@ impl std::ops::Add for Text<'_> { } } -impl<'a> std::ops::AddAssign> for Text<'a> { +impl<'a> core::ops::AddAssign> for Text<'a> { fn add_assign(&mut self, line: Line<'a>) { self.push_line(line); } @@ -743,7 +743,7 @@ impl Styled for Text<'_> { #[cfg(test)] mod tests { - use std::iter; + use core::iter; use rstest::{fixture, rstest}; diff --git a/ratatui-core/src/widgets/stateful_widget.rs b/ratatui-core/src/widgets/stateful_widget.rs index aa6ced4c..2f973d53 100644 --- a/ratatui-core/src/widgets/stateful_widget.rs +++ b/ratatui-core/src/widgets/stateful_widget.rs @@ -170,7 +170,7 @@ mod tests { impl StatefulWidget for Bytes { type State = [u8]; fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { - let slice = std::str::from_utf8(state).unwrap(); + let slice = core::str::from_utf8(state).unwrap(); Line::from(format!("Bytes: {slice}")).render(area, buf); } }