feat(no_std): remove redundant std usages in ratatui-core (#1753)

Resolves https://github.com/ratatui/ratatui/issues/1751
This commit is contained in:
Jagoda Estera Ślązak
2025-04-04 05:02:54 +02:00
committed by GitHub
parent 416ebdf8c8
commit ebe10cd81f
21 changed files with 68 additions and 71 deletions

1
Cargo.lock generated
View File

@@ -2551,6 +2551,7 @@ dependencies = [
"cassowary",
"compact_str",
"document-features",
"hashbrown",
"indoc",
"itertools 0.13.0",
"lru",

View File

@@ -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"

View File

@@ -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<u16>, line_count: u16)
-> io::Result<()>;
fn scroll_region_up(&mut self, region: ops::Range<u16>, 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<u16>,
line_count: u16,
) -> io::Result<()>;
fn scroll_region_down(&mut self, region: ops::Range<u16>, line_count: u16) -> io::Result<()>;
}
#[cfg(test)]

View File

@@ -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<u16>, scroll_by: u16) -> io::Result<()> {
fn scroll_region_up(&mut self, region: ops::Range<u16>, 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<u16>,
scroll_by: u16,
) -> io::Result<()> {
fn scroll_region_down(&mut self, region: ops::Range<u16>, 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<const L: usize, const M: usize, const N: usize>(
#[case] initial_screen: [&'static str; L],
#[case] range: std::ops::Range<u16>,
#[case] range: ops::Range<u16>,
#[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<const M: usize, const N: usize>(
#[case] initial_screen: [&'static str; M],
#[case] range: std::ops::Range<u16>,
#[case] range: ops::Range<u16>,
#[case] scroll_by: u16,
#[case] expected_buffer: [&'static str; N],
) {

View File

@@ -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};

View File

@@ -1,4 +1,4 @@
use std::fmt;
use core::fmt;
use strum::EnumIs;

View File

@@ -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;

View File

@@ -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))]

View File

@@ -1,5 +1,5 @@
#![warn(missing_docs)]
use std::fmt;
use core::fmt;
use crate::layout::Rect;

View File

@@ -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};

View File

@@ -1,5 +1,5 @@
#![warn(missing_docs)]
use std::fmt;
use core::fmt;
use crate::layout::Rect;

View File

@@ -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;

View File

@@ -68,7 +68,7 @@
//!
//! [`Span`]: crate::text::Span
use std::fmt;
use core::fmt;
use bitflags::bitflags;
pub use color::{Color, ParseColorError};

View File

@@ -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};

View File

@@ -1,4 +1,4 @@
use std::fmt;
use core::fmt;
use crate::style::{Color, Modifier, Style};
use crate::text::Span;

View File

@@ -1,4 +1,4 @@
use std::fmt;
use core::fmt;
use crate::layout::Rect;

View File

@@ -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<Span<'a>> {
pub fn iter(&self) -> core::slice::Iter<Span<'a>> {
self.spans.iter()
}
/// Returns a mutable iterator over the spans of this line.
pub fn iter_mut(&mut self) -> std::slice::IterMut<Span<'a>> {
pub fn iter_mut(&mut self) -> core::slice::IterMut<Span<'a>> {
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<Span<'a>>;
type IntoIter = alloc::vec::IntoIter<Span<'a>>;
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<Span<'a>> for Line<'a> {
impl<'a> core::ops::Add<Span<'a>> for Line<'a> {
type Output = Self;
fn add(mut self, rhs: Span<'a>) -> Self::Output {
@@ -648,7 +648,7 @@ impl<'a> std::ops::Add<Span<'a>> 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<Self> for Line<'a> {
impl<'a> core::ops::Add<Self> for Line<'a> {
type Output = Text<'a>;
fn add(self, rhs: Self) -> Self::Output {
@@ -656,7 +656,7 @@ impl<'a> std::ops::Add<Self> for Line<'a> {
}
}
impl<'a> std::ops::AddAssign<Span<'a>> for Line<'a> {
impl<'a> core::ops::AddAssign<Span<'a>> 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};

View File

@@ -1,5 +1,5 @@
use std::borrow::Cow;
use std::fmt;
use alloc::borrow::Cow;
use core::fmt;
use crate::text::Text;

View File

@@ -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<Self> for Span<'a> {
impl<'a> core::ops::Add<Self> for Span<'a> {
type Output = Line<'a>;
fn add(self, rhs: Self) -> Self::Output {

View File

@@ -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<Line<'a>> {
pub fn iter(&self) -> core::slice::Iter<Line<'a>> {
self.lines.iter()
}
/// Returns an iterator that allows modifying each line.
pub fn iter_mut(&mut self) -> std::slice::IterMut<Line<'a>> {
pub fn iter_mut(&mut self) -> core::slice::IterMut<Line<'a>> {
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<Self::Item>;
type IntoIter = alloc::vec::IntoIter<Self::Item>;
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<Line<'a>> for Text<'a> {
impl<'a> core::ops::Add<Line<'a>> for Text<'a> {
type Output = Self;
fn add(mut self, line: Line<'a>) -> Self::Output {
@@ -653,7 +653,7 @@ impl<'a> std::ops::Add<Line<'a>> for Text<'a> {
/// Adds two `Text` together.
///
/// This ignores the style and alignment of the second `Text`.
impl std::ops::Add<Self> for Text<'_> {
impl core::ops::Add<Self> for Text<'_> {
type Output = Self;
fn add(mut self, text: Self) -> Self::Output {
@@ -662,7 +662,7 @@ impl std::ops::Add<Self> for Text<'_> {
}
}
impl<'a> std::ops::AddAssign<Line<'a>> for Text<'a> {
impl<'a> core::ops::AddAssign<Line<'a>> 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};

View File

@@ -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);
}
}