feat(no_std)!: make ratatui compatible with #![no_std] (#1794)
Resolves #1781 This PR makes it possible to compile ratatui with `#![no_std]`. Also makes me answer "We Are So Embedded" to "Are We Embedded Yet?"
This commit is contained in:
committed by
GitHub
parent
ab48c06171
commit
3e1c72fb27
@@ -22,6 +22,7 @@ This is a quick summary of the sections below:
|
||||
- `TestBackend` now uses `core::convert::Infallible` for error handling instead of `std::io::Error`
|
||||
- Disabling `default-features` will now disable layout cache, which can have a negative impact on performance
|
||||
- `Layout::init_cache` and `Layout::DEFAULT_CACHE_SIZE` are now only available if `layout-cache` feature is enabled
|
||||
- Disabling `default-features` suppresses the error message if `show_cursor()` fails when dropping `Terminal`
|
||||
- [v0.29.0](#v0290)
|
||||
- `Sparkline::data` takes `IntoIterator<Item = SparklineBar>` instead of `&[u64]` and is no longer const
|
||||
- Removed public fields from `Rect` iterators
|
||||
@@ -86,6 +87,13 @@ This is a quick summary of the sections below:
|
||||
|
||||
## Unreleased (0.30.0)
|
||||
|
||||
### Disabling `default-features` suppresses the error message if `show_cursor()` fails when dropping `Terminal` ([#1794])
|
||||
|
||||
[#1794]: https://github.com/ratatui/ratatui/pull/1794
|
||||
|
||||
Since disabling `default-features` disables `std`, printing to stderr is not possible. It is
|
||||
recommended to re-enable `std` when not using Ratatui in `no_std` environment.
|
||||
|
||||
### `Layout::init_cache` and `Layout::DEFAULT_CACHE_SIZE` are now only available if `layout-cache` feature is enabled ([#1795])
|
||||
|
||||
[#1795]: https://github.com/ratatui/ratatui/pull/1795
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use alloc::format;
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use core::iter;
|
||||
use core::num::NonZeroUsize;
|
||||
use std::dbg;
|
||||
|
||||
use hashbrown::HashMap;
|
||||
use itertools::Itertools;
|
||||
@@ -1020,8 +1018,9 @@ fn changes_to_rects(
|
||||
/// please leave this here as it's useful for debugging unit tests when we make any changes to
|
||||
/// layout code - we should replace this with tracing in the future.
|
||||
#[expect(dead_code)]
|
||||
#[cfg(feature = "std")]
|
||||
fn debug_elements(elements: &[Element], changes: &HashMap<Variable, f64>) {
|
||||
let variables = format!(
|
||||
let variables = alloc::format!(
|
||||
"{:?}",
|
||||
elements
|
||||
.iter()
|
||||
@@ -1031,7 +1030,7 @@ fn debug_elements(elements: &[Element], changes: &HashMap<Variable, f64>) {
|
||||
))
|
||||
.collect::<Vec<(f64, f64)>>()
|
||||
);
|
||||
dbg!(variables);
|
||||
std::dbg!(variables);
|
||||
}
|
||||
|
||||
/// A container used by the solver inside split
|
||||
|
||||
@@ -43,9 +43,9 @@
|
||||
#![warn(clippy::std_instead_of_alloc)]
|
||||
#![warn(clippy::alloc_instead_of_core)]
|
||||
|
||||
extern crate std;
|
||||
|
||||
extern crate alloc;
|
||||
#[cfg(feature = "std")]
|
||||
extern crate std;
|
||||
|
||||
pub mod backend;
|
||||
pub mod buffer;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use std::eprintln;
|
||||
|
||||
use crate::backend::{Backend, ClearType};
|
||||
use crate::buffer::{Buffer, Cell};
|
||||
use crate::layout::{Position, Rect, Size};
|
||||
@@ -91,8 +89,10 @@ where
|
||||
fn drop(&mut self) {
|
||||
// Attempt to restore the cursor state
|
||||
if self.hidden_cursor {
|
||||
#[allow(unused_variables)]
|
||||
if let Err(err) = self.show_cursor() {
|
||||
eprintln!("Failed to show the cursor: {err}");
|
||||
#[cfg(feature = "std")]
|
||||
std::eprintln!("Failed to show the cursor: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#![no_std]
|
||||
// show the feature flags in the generated documentation
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
@@ -80,7 +81,6 @@
|
||||
//!
|
||||
//! This project is licensed under the MIT License. See the [LICENSE](../LICENSE) file for details.
|
||||
|
||||
#![no_std]
|
||||
#![warn(clippy::std_instead_of_core)]
|
||||
#![warn(clippy::std_instead_of_alloc)]
|
||||
#![warn(clippy::alloc_instead_of_core)]
|
||||
|
||||
@@ -31,11 +31,14 @@ rustdoc-args = ["--cfg", "docsrs"]
|
||||
default = ["crossterm", "underline-color", "all-widgets", "macros", "layout-cache"]
|
||||
#! Generally an application will only use one backend, so you should only enable one of the following features:
|
||||
## enables the [`CrosstermBackend`](backend::CrosstermBackend) backend and adds a dependency on [`crossterm`].
|
||||
crossterm = ["dep:ratatui-crossterm"]
|
||||
crossterm = ["std", "dep:ratatui-crossterm"]
|
||||
## enables the [`TermionBackend`](backend::TermionBackend) backend and adds a dependency on [`termion`].
|
||||
termion = ["dep:ratatui-termion"]
|
||||
termion = ["std", "dep:ratatui-termion"]
|
||||
## enables the [`TermwizBackend`](backend::TermwizBackend) backend and adds a dependency on [`termwiz`].
|
||||
termwiz = ["dep:ratatui-termwiz"]
|
||||
termwiz = ["std", "dep:ratatui-termwiz"]
|
||||
|
||||
## enables std
|
||||
std = ["ratatui-core/std"]
|
||||
|
||||
#! The following optional features are available for all backends:
|
||||
## enables serialization and deserialization of style and color types using the [`serde`] crate.
|
||||
@@ -50,7 +53,7 @@ serde = [
|
||||
]
|
||||
|
||||
## enables layout cache
|
||||
layout-cache = ["ratatui-core/layout-cache"]
|
||||
layout-cache = ["std", "ratatui-core/layout-cache"]
|
||||
|
||||
## enables conversions from colors in the [`palette`] crate to [`Color`](crate::style::Color).
|
||||
palette = ["ratatui-core/palette", "dep:palette"]
|
||||
|
||||
@@ -198,7 +198,7 @@ pub fn try_init_with_options(options: TerminalOptions) -> io::Result<DefaultTerm
|
||||
pub fn restore() {
|
||||
if let Err(err) = try_restore() {
|
||||
// There's not much we can do if restoring the terminal fails, so we just print the error
|
||||
eprintln!("Failed to restore terminal: {err}");
|
||||
std::eprintln!("Failed to restore terminal: {err}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ pub fn try_restore() -> io::Result<()> {
|
||||
/// original panic hook. This ensures that the terminal is left in a good state when a panic occurs.
|
||||
fn set_panic_hook() {
|
||||
let hook = std::panic::take_hook();
|
||||
std::panic::set_hook(Box::new(move |info| {
|
||||
std::panic::set_hook(alloc::boxed::Box::new(move |info| {
|
||||
restore();
|
||||
hook(info);
|
||||
}));
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#![no_std]
|
||||
// show the feature flags in the generated documentation
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
@@ -323,6 +324,14 @@
|
||||
//! [Forum]: https://forum.ratatui.rs
|
||||
//! [Sponsors Badge]: https://img.shields.io/github/sponsors/ratatui?logo=github&style=flat-square&color=1370D3
|
||||
|
||||
#![warn(clippy::std_instead_of_core)]
|
||||
#![warn(clippy::std_instead_of_alloc)]
|
||||
#![warn(clippy::alloc_instead_of_core)]
|
||||
|
||||
extern crate alloc;
|
||||
#[cfg(feature = "std")]
|
||||
extern crate std;
|
||||
|
||||
/// re-export the `palette` crate so that users don't have to add it as a dependency
|
||||
#[cfg(feature = "palette")]
|
||||
pub use palette;
|
||||
|
||||
@@ -81,6 +81,11 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::format;
|
||||
use alloc::string::{String, ToString};
|
||||
|
||||
use rstest::{fixture, rstest};
|
||||
|
||||
use super::*;
|
||||
@@ -129,7 +134,7 @@ mod tests {
|
||||
impl StatefulWidgetRef for Bytes {
|
||||
type State = [u8];
|
||||
fn render_ref(&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);
|
||||
}
|
||||
}
|
||||
@@ -145,7 +150,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use alloc::string::String;
|
||||
|
||||
use super::Widget;
|
||||
use crate::buffer::Buffer;
|
||||
use crate::layout::Rect;
|
||||
@@ -166,6 +168,10 @@ impl<W: WidgetRef> WidgetRef for Option<W> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use rstest::{fixture, rstest};
|
||||
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user