diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51c6f7b26..d83bc78bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,8 +51,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] rust: [stable] include: - # Make 1.64 MSRV, as it's Tonic 0.10's MSRV. - - rust: 1.64.0 + - rust: 1.74.0 os: ubuntu-latest # Try to build on the latest nightly. This job is allowed to fail, but # it's useful to help catch bugs in upcoming Rust versions. diff --git a/Cargo.lock b/Cargo.lock index 0efb15ed8..abf284383 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,18 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.0.5" @@ -26,6 +38,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "anyhow" version = "1.0.56" @@ -184,6 +202,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" +[[package]] +name = "castaway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +dependencies = [ + "rustversion", +] + [[package]] name = "cc" version = "1.0.73" @@ -287,6 +314,19 @@ dependencies = [ "memchr", ] +[[package]] +name = "compact_str" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "ryu", + "static_assertions", +] + [[package]] name = "concolor" version = "0.0.8" @@ -410,11 +450,11 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.26.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "crossterm_winapi", "futures-core", "libc", @@ -701,6 +741,10 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "hdrhistogram" @@ -865,6 +909,12 @@ dependencies = [ "hashbrown 0.14.3", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + [[package]] name = "instant" version = "0.1.12" @@ -914,6 +964,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.6" @@ -960,6 +1019,15 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown 0.14.3", +] + [[package]] name = "matchers" version = "0.1.0" @@ -1147,6 +1215,12 @@ dependencies = [ "windows-sys 0.34.0", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1315,13 +1389,20 @@ dependencies = [ [[package]] name = "ratatui" -version = "0.20.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc0d032bccba900ee32151ec0265667535c230169f5a011154cdcd984e16829" +checksum = "a564a852040e82671dc50a37d88f3aa83bbc690dfc6844cfe7a2591620206a80" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cassowary", + "compact_str", "crossterm", + "indoc", + "itertools 0.12.1", + "lru", + "paste", + "stability", + "strum", "unicode-segmentation", "unicode-width", ] @@ -1618,12 +1699,50 @@ dependencies = [ "winapi", ] +[[package]] +name = "stability" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a" +dependencies = [ + "quote", + "syn 2.0.33", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.33", +] + [[package]] name = "syn" version = "1.0.90" @@ -2119,6 +2238,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wait-timeout" version = "0.2.0" @@ -2325,3 +2450,23 @@ name = "yansi" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.33", +] diff --git a/console-api/Cargo.toml b/console-api/Cargo.toml index 75d1c2f17..626862744 100644 --- a/console-api/Cargo.toml +++ b/console-api/Cargo.toml @@ -3,7 +3,7 @@ name = "console-api" version = "0.6.0" license = "MIT" edition = "2021" -rust-version = "1.64.0" +rust-version = "1.74.0" authors = ["Eliza Weisman ", "Tokio Contributors ",] readme = "README.md" repository = "https://github.com/tokio-rs/console/" diff --git a/console-subscriber/Cargo.toml b/console-subscriber/Cargo.toml index 6e7e48cd4..f7a17d6e2 100644 --- a/console-subscriber/Cargo.toml +++ b/console-subscriber/Cargo.toml @@ -3,7 +3,7 @@ name = "console-subscriber" version = "0.2.0" license = "MIT" edition = "2021" -rust-version = "1.64.0" +rust-version = "1.74.0" authors = ["Eliza Weisman ", "Tokio Contributors ",] readme = "README.md" repository = "https://github.com/tokio-rs/console/" diff --git a/console-subscriber/README.md b/console-subscriber/README.md index 12ac263cb..e9546d23d 100644 --- a/console-subscriber/README.md +++ b/console-subscriber/README.md @@ -245,7 +245,7 @@ console project. ## Supported Rust Versions The Tokio console is built against the latest stable release. The minimum -supported version is 1.64. The current Tokio console version is not guaranteed +supported version is 1.74. The current Tokio console version is not guaranteed to build on Rust versions earlier than the minimum supported version. ## License diff --git a/tokio-console/Cargo.toml b/tokio-console/Cargo.toml index b9dfcd151..de01b8b7f 100644 --- a/tokio-console/Cargo.toml +++ b/tokio-console/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.10" license = "MIT" repository = "https://github.com/tokio-rs/console" edition = "2021" -rust-version = "1.64.0" +rust-version = "1.74.0" authors = ["Eliza Weisman ", "Tokio Contributors ",] readme = "README.md" default-run = "tokio-console" @@ -40,13 +40,13 @@ clap_complete = "~4.1.6" tokio = { version = "1", features = ["full", "rt-multi-thread"] } tonic = { version = "0.10", features = ["transport"] } futures = "0.3" -ratatui = { version = "0.20.1", default-features = false, features = ["crossterm"] } +ratatui = { version = "0.26.2", default-features = false, features = ["crossterm"] } tower = "0.4.12" tracing = "0.1" tracing-subscriber = { version = "0.3" } tracing-journald = { version = "0.2", optional = true } prost-types = "0.12" -crossterm = { version = "0.26.1", features = ["event-stream"] } +crossterm = { version = "0.27.0", features = ["event-stream"] } color-eyre = { version = "0.6", features = ["issue-url"] } hdrhistogram = { version = "7.3.0", default-features = false, features = ["serialization"] } # Keep this in sync with the version from `tonic`. diff --git a/tokio-console/README.md b/tokio-console/README.md index 86cbd3945..8645a89ff 100644 --- a/tokio-console/README.md +++ b/tokio-console/README.md @@ -236,7 +236,7 @@ console project. ## Supported Rust Versions The Tokio console is built against the latest stable release. The minimum -supported version is 1.64. The current Tokio console version is not guaranteed +supported version is 1.74. The current Tokio console version is not guaranteed to build on Rust versions earlier than the minimum supported version. ## License diff --git a/tokio-console/src/conn.rs b/tokio-console/src/conn.rs index 8cfd4bf51..471035c19 100644 --- a/tokio-console/src/conn.rs +++ b/tokio-console/src/conn.rs @@ -183,10 +183,10 @@ impl Connection { } } - pub fn render(&self, styles: &crate::view::Styles) -> ratatui::text::Spans { + pub fn render(&self, styles: &crate::view::Styles) -> ratatui::text::Line { use ratatui::{ style::{Color, Modifier}, - text::{Span, Spans}, + text::{Line, Span}, }; let state = match self.state { State::Connected { .. } => Span::styled( @@ -202,7 +202,7 @@ impl Connection { styles.fg(Color::Yellow).add_modifier(Modifier::BOLD), ), }; - Spans::from(vec![ + Line::from(vec![ Span::raw("connection: "), Span::raw(self.target.to_string()), Span::raw(" "), diff --git a/tokio-console/src/input.rs b/tokio-console/src/input.rs index 088d5b771..47cba9b7b 100644 --- a/tokio-console/src/input.rs +++ b/tokio-console/src/input.rs @@ -3,6 +3,18 @@ // input-handling mechanisms in the background... pub use crossterm::event::*; +/// Crossterm on windows reports key release and repeat events which have the +/// effect of duplicating key presses. This function filters out those events. +pub fn should_ignore_key_event(input: &Event) -> bool { + matches!( + input, + Event::Key(KeyEvent { + kind: KeyEventKind::Release | KeyEventKind::Repeat, + .. + }) + ) +} + pub fn should_quit(input: &Event) -> bool { use Event::*; use KeyCode::*; @@ -53,3 +65,38 @@ pub(crate) fn is_esc(event: &Event) -> bool { }) ) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ignore_key_repeat_and_release_events() { + let event = Event::Key(KeyEvent { + code: KeyCode::Char('a'), + modifiers: KeyModifiers::empty(), + kind: KeyEventKind::Press, + state: KeyEventState::empty(), + }); + + assert!(!should_ignore_key_event(&event)); + + let event = Event::Key(KeyEvent { + code: KeyCode::Char('a'), + modifiers: KeyModifiers::empty(), + kind: KeyEventKind::Release, + state: KeyEventState::empty(), + }); + + assert!(should_ignore_key_event(&event)); + + let event = Event::Key(KeyEvent { + code: KeyCode::Char('a'), + modifiers: KeyModifiers::empty(), + kind: KeyEventKind::Repeat, + state: KeyEventState::empty(), + }); + + assert!(should_ignore_key_event(&event)); + } +} diff --git a/tokio-console/src/main.rs b/tokio-console/src/main.rs index 421c660a7..6b8ed54cf 100644 --- a/tokio-console/src/main.rs +++ b/tokio-console/src/main.rs @@ -2,21 +2,17 @@ use color_eyre::{eyre::eyre, Help, SectionExt}; use console_api::tasks::TaskDetails; use state::State; -use futures::{ - future, - stream::{StreamExt, TryStreamExt}, -}; +use futures::stream::StreamExt; use ratatui::{ layout::{Constraint, Direction, Layout}, style::Color, - text::{Span, Spans}, + text::{Line, Span}, widgets::{Paragraph, Wrap}, }; use tokio::sync::{mpsc, watch}; use crate::{ config::AllowedWarnings, - input::{Event, KeyEvent, KeyEventKind}, view::{bold, UpdateKind}, }; @@ -78,15 +74,7 @@ async fn main() -> color_eyre::Result<()> { let mut state = State::default() .with_task_linters(warnings.into_iter().map(|lint| lint.into())) .with_retain_for(retain_for); - let mut input = Box::pin(input::EventStream::new().try_filter(|event| { - future::ready(!matches!( - event, - Event::Key(KeyEvent { - kind: KeyEventKind::Release, - .. - }) - )) - })); + let mut input = Box::pin(input::EventStream::new()); let mut view = view::View::new(styles); loop { @@ -95,6 +83,11 @@ async fn main() -> color_eyre::Result<()> { let input = input .ok_or_else(|| eyre!("keyboard input stream ended early")) .with_section(|| "this is probably a bug".header("Note:"))??; + + if input::should_ignore_key_event(&input) { + continue; + } + if input::should_quit(&input) { return Ok(()); } @@ -156,9 +149,7 @@ async fn main() -> color_eyre::Result<()> { let mut header_text = conn.render(&view.styles); if state.is_paused() { - header_text - .0 - .push(Span::styled(" PAUSED", view.styles.fg(Color::Red))); + header_text.push_span(Span::styled(" PAUSED", view.styles.fg(Color::Red))); } let dropped_async_ops_state = state.async_ops_state().dropped_events(); let dropped_tasks_state = state.tasks_state().dropped_events(); @@ -174,13 +165,13 @@ async fn main() -> color_eyre::Result<()> { if dropped_resources_state > 0 { dropped_texts.push(format!("{} resources", dropped_resources_state)) } - header_text.0.push(Span::styled( + header_text.push_span(Span::styled( format!(" dropped: {}", dropped_texts.join(", ")), view.styles.fg(Color::Red), )); } let header = Paragraph::new(header_text).wrap(Wrap { trim: true }); - let view_controls = Paragraph::new(Spans::from(vec![ + let view_controls = Paragraph::new(Line::from(vec![ Span::raw("views: "), bold("t"), Span::raw(" = tasks, "), diff --git a/tokio-console/src/view/async_ops.rs b/tokio-console/src/view/async_ops.rs index 000319cc3..1cda2b48a 100644 --- a/tokio-console/src/view/async_ops.rs +++ b/tokio-console/src/view/async_ops.rs @@ -15,7 +15,7 @@ use crate::{ use ratatui::{ layout, style::{self, Color, Style}, - text::Spans, + text::Line, widgets::{Cell, Row, Table}, }; @@ -56,10 +56,10 @@ impl TableList<9> for AsyncOpsTable { Self::HEADER[8].len() + 1, ]; - fn render( + fn render( table_list_state: &mut TableListState, styles: &view::Styles, - frame: &mut ratatui::terminal::Frame, + frame: &mut ratatui::terminal::Frame, area: layout::Rect, state: &mut State, ctx: Self::Context, @@ -144,7 +144,7 @@ impl TableList<9> for AsyncOpsTable { dur_cell(async_op.busy(now)), dur_cell(async_op.idle(now)), Cell::from(polls_width.update_str(async_op.total_polls().to_string())), - Cell::from(Spans::from( + Cell::from(Line::from( async_op .formatted_attributes() .iter() @@ -184,9 +184,9 @@ impl TableList<9> for AsyncOpsTable { .style(header_style); let table = if table_list_state.sort_descending { - Table::new(rows) + Table::default().rows(rows) } else { - Table::new(rows.rev()) + Table::default().rows(rows.rev()) }; let block = styles.border_block().title(vec![bold(format!( diff --git a/tokio-console/src/view/controls.rs b/tokio-console/src/view/controls.rs index bf9972532..c8e8f86b2 100644 --- a/tokio-console/src/view/controls.rs +++ b/tokio-console/src/view/controls.rs @@ -2,7 +2,7 @@ use crate::view::{self, bold}; use ratatui::{ layout, - text::{Span, Spans, Text}, + text::{Line, Span, Text}, widgets::{Paragraph, Widget}, }; @@ -37,21 +37,21 @@ impl Controls { area: &layout::Rect, styles: &view::Styles, ) -> Self { - let mut spans_controls = Vec::with_capacity(view_controls.len() + UNIVERSAL_CONTROLS.len()); - spans_controls.extend(view_controls.iter().map(|c| c.to_spans(styles, 0))); - spans_controls.extend(UNIVERSAL_CONTROLS.iter().map(|c| c.to_spans(styles, 0))); + let mut line_controls = Vec::with_capacity(view_controls.len() + UNIVERSAL_CONTROLS.len()); + line_controls.extend(view_controls.iter().map(|c| c.to_spans(styles, 0))); + line_controls.extend(UNIVERSAL_CONTROLS.iter().map(|c| c.to_spans(styles, 0))); - let mut lines = vec![Spans::from(vec![Span::from("controls: ")])]; + let mut lines = vec![Line::from(vec![Span::from("controls: ")])]; let mut current_line = lines.last_mut().expect("This vector is never empty"); let separator = Span::from(", "); - let controls_count: usize = spans_controls.len(); - for (idx, spans) in spans_controls.into_iter().enumerate() { + let controls_count: usize = line_controls.len(); + for (idx, line) in line_controls.into_iter().enumerate() { // If this is the first item on this line - or first item on the // first line, then always include it - even if it goes beyond the // line width, not much we can do anyway. if idx == 0 || current_line.width() == 0 { - current_line.0.extend(spans.0); + current_line.spans.extend(line.spans); continue; } @@ -66,7 +66,7 @@ impl Controls { let total_width = current_line.width() + separator.width() - + spans.width() + + line.width() + needed_trailing_separator_width; // If the current item fits on this line, append it. @@ -74,11 +74,11 @@ impl Controls { // width in the previous loop iteration - and then create a new // line for the current item. if total_width <= area.width as usize { - current_line.0.push(separator.clone()); - current_line.0.extend(spans.0); + current_line.push_span(separator.clone()); + current_line.spans.extend(line.spans); } else { - current_line.0.push(separator.clone()); - lines.push(spans); + current_line.push_span(separator.clone()); + lines.push(line); current_line = lines.last_mut().expect("This vector is never empty"); } } @@ -106,7 +106,7 @@ pub(crate) fn controls_paragraph<'a>( styles: &view::Styles, ) -> Paragraph<'a> { let mut spans = Vec::with_capacity(1 + view_controls.len() + UNIVERSAL_CONTROLS.len()); - spans.push(Spans::from(vec![Span::raw("controls:")])); + spans.push(Line::from(vec![Span::raw("controls:")])); spans.extend(view_controls.iter().map(|c| c.to_spans(styles, 2))); spans.extend(UNIVERSAL_CONTROLS.iter().map(|c| c.to_spans(styles, 2))); @@ -137,7 +137,7 @@ pub(crate) struct KeyDisplay { } impl ControlDisplay { - pub(crate) fn to_spans(&self, styles: &view::Styles, indent: usize) -> Spans<'static> { + pub(crate) fn to_spans(&self, styles: &view::Styles, indent: usize) -> Line<'static> { let mut spans = Vec::new(); spans.push(Span::from(" ".repeat(indent))); @@ -153,6 +153,6 @@ impl ControlDisplay { })); } - Spans::from(spans) + Line::from(spans) } } diff --git a/tokio-console/src/view/help.rs b/tokio-console/src/view/help.rs index de249db61..297385967 100644 --- a/tokio-console/src/view/help.rs +++ b/tokio-console/src/view/help.rs @@ -21,10 +21,10 @@ impl<'a> HelpView<'a> { } } - pub(crate) fn render( + pub(crate) fn render( &mut self, styles: &view::Styles, - frame: &mut ratatui::terminal::Frame, + frame: &mut ratatui::terminal::Frame, _area: layout::Rect, _state: &mut State, ) { diff --git a/tokio-console/src/view/mod.rs b/tokio-console/src/view/mod.rs index d61ab7c45..6dda97c96 100644 --- a/tokio-console/src/view/mod.rs +++ b/tokio-console/src/view/mod.rs @@ -217,9 +217,9 @@ impl View { input::is_help_toggle(event) || (self.show_help_modal && input::is_esc(event)) } - pub(crate) fn render( + pub(crate) fn render( &mut self, - frame: &mut ratatui::terminal::Frame, + frame: &mut ratatui::terminal::Frame, area: layout::Rect, state: &mut State, ) { diff --git a/tokio-console/src/view/percentiles.rs b/tokio-console/src/view/percentiles.rs index 207cc3ad7..20343c66a 100644 --- a/tokio-console/src/view/percentiles.rs +++ b/tokio-console/src/view/percentiles.rs @@ -1,7 +1,7 @@ use std::time::Duration; use ratatui::{ - text::{Spans, Text}, + text::{Line, Text}, widgets::{Paragraph, Widget}, }; @@ -51,7 +51,7 @@ impl<'a> Percentiles<'a> { .iter() .map(move |i| (*i, histogram.value_at_percentile(*i))); let percentiles = pairs.map(|pair| { - Spans::from(vec![ + Line::from(vec![ bold(format!("p{:>2}: ", pair.0)), self.styles.time_units( Duration::from_nanos(pair.1), diff --git a/tokio-console/src/view/resource.rs b/tokio-console/src/view/resource.rs index 8c85203ac..5a1554c29 100644 --- a/tokio-console/src/view/resource.rs +++ b/tokio-console/src/view/resource.rs @@ -14,7 +14,7 @@ use crate::{ use once_cell::sync::OnceCell; use ratatui::{ layout::{self, Layout}, - text::{Span, Spans, Text}, + text::{Line, Span, Text}, widgets::Paragraph, }; use std::{cell::RefCell, rc::Rc}; @@ -38,10 +38,10 @@ impl ResourceView { self.async_ops_table.update_input(event) } - pub(crate) fn render( + pub(crate) fn render( &mut self, styles: &view::Styles, - frame: &mut ratatui::terminal::Frame, + frame: &mut ratatui::terminal::Frame, area: layout::Rect, state: &mut State, ) { @@ -78,17 +78,17 @@ impl ResourceView { .split(stats_area); let overview = vec![ - Spans::from(vec![bold("ID: "), Span::raw(resource.id_str())]), - Spans::from(vec![bold("Parent ID: "), Span::raw(resource.parent())]), - Spans::from(vec![bold("Kind: "), Span::raw(resource.kind())]), - Spans::from(vec![bold("Target: "), Span::raw(resource.target())]), - Spans::from(vec![ + Line::from(vec![bold("ID: "), Span::raw(resource.id_str())]), + Line::from(vec![bold("Parent ID: "), Span::raw(resource.parent())]), + Line::from(vec![bold("Kind: "), Span::raw(resource.kind())]), + Line::from(vec![bold("Target: "), Span::raw(resource.target())]), + Line::from(vec![ bold("Type: "), Span::raw(resource.concrete_type()), Span::raw(" "), resource.type_visibility().render(styles), ]), - Spans::from(vec![bold("Location: "), Span::raw(resource.location())]), + Line::from(vec![bold("Location: "), Span::raw(resource.location())]), ]; let mut fields = Text::default(); @@ -97,7 +97,7 @@ impl ResourceView { .formatted_attributes() .iter() .cloned() - .map(Spans::from), + .map(Line::from), ); let resource_widget = diff --git a/tokio-console/src/view/resources.rs b/tokio-console/src/view/resources.rs index 124ba22d5..b0cd39841 100644 --- a/tokio-console/src/view/resources.rs +++ b/tokio-console/src/view/resources.rs @@ -14,7 +14,7 @@ use crate::{ use ratatui::{ layout, style::{self, Color, Style}, - text::Spans, + text::Line, widgets::{Cell, Row, Table}, }; @@ -50,10 +50,10 @@ impl TableList<9> for ResourcesTable { Self::HEADER[8].len() + 1, ]; - fn render( + fn render( table_list_state: &mut TableListState, styles: &view::Styles, - frame: &mut ratatui::terminal::Frame, + frame: &mut ratatui::terminal::Frame, area: layout::Rect, state: &mut State, _: Self::Context, @@ -114,14 +114,14 @@ impl TableList<9> for ResourcesTable { Cell::from(type_width.update_str(resource.concrete_type()).to_owned()), Cell::from(resource.type_visibility().render(styles)), Cell::from(location_width.update_str(resource.location()).to_owned()), - Cell::from(Spans::from( + Cell::from( resource .formatted_attributes() .iter() .flatten() .cloned() - .collect::>(), - )), + .collect::(), + ), ]); if resource.dropped() { @@ -154,9 +154,9 @@ impl TableList<9> for ResourcesTable { .style(header_style); let table = if table_list_state.sort_descending { - Table::new(rows) + Table::default().rows(rows) } else { - Table::new(rows.rev()) + Table::default().rows(rows.rev()) }; let block = styles.border_block().title(vec![bold(format!( diff --git a/tokio-console/src/view/table.rs b/tokio-console/src/view/table.rs index 10fdd16dc..40ffc8757 100644 --- a/tokio-console/src/view/table.rs +++ b/tokio-console/src/view/table.rs @@ -23,10 +23,10 @@ pub(crate) trait TableList { const HEADER: &'static [&'static str; N]; const WIDTHS: &'static [usize; N]; - fn render( + fn render( state: &mut TableListState, styles: &view::Styles, - frame: &mut ratatui::terminal::Frame, + frame: &mut ratatui::terminal::Frame, area: layout::Rect, state: &mut state::State, cx: Self::Context, @@ -168,10 +168,10 @@ impl, const N: usize> TableListState { .unwrap_or_default() } - pub(in crate::view) fn render( + pub(in crate::view) fn render( &mut self, styles: &view::Styles, - frame: &mut ratatui::terminal::Frame, + frame: &mut ratatui::terminal::Frame, area: layout::Rect, state: &mut state::State, ctx: T::Context, diff --git a/tokio-console/src/view/task.rs b/tokio-console/src/view/task.rs index 8a6494464..accb3fb07 100644 --- a/tokio-console/src/view/task.rs +++ b/tokio-console/src/view/task.rs @@ -11,7 +11,7 @@ use crate::{ }; use ratatui::{ layout::{self, Layout}, - text::{Span, Spans, Text}, + text::{Line, Span, Text}, widgets::{List, ListItem, Paragraph}, }; use std::{ @@ -35,10 +35,10 @@ impl TaskView { // TODO :D } - pub(crate) fn render( + pub(crate) fn render( &mut self, styles: &view::Styles, - frame: &mut ratatui::terminal::Frame, + frame: &mut ratatui::terminal::Frame, area: layout::Rect, now: SystemTime, ) { @@ -60,7 +60,7 @@ impl TaskView { .warnings() .iter() .map(|linter| { - ListItem::new(Text::from(Spans::from(vec![ + ListItem::new(Text::from(Line::from(vec![ styles.warning_wide(), // TODO(eliza): it would be nice to handle singular vs plural... Span::from(linter.format(task)), @@ -140,20 +140,17 @@ impl TaskView { // Just preallocate capacity for ID, name, target, total, busy, and idle. let mut overview = Vec::with_capacity(8); - overview.push(Spans::from(vec![ + overview.push(Line::from(vec![ bold("ID: "), Span::raw(format!("{} ", task.id_str())), task.state().render(styles), ])); if let Some(name) = task.name() { - overview.push(Spans::from(vec![bold("Name: "), Span::raw(name)])); + overview.push(Line::from(vec![bold("Name: "), Span::raw(name)])); } - overview.push(Spans::from(vec![ - bold("Target: "), - Span::raw(task.target()), - ])); + overview.push(Line::from(vec![bold("Target: "), Span::raw(task.target())])); let title = "Location: "; let location_max_width = stats_area[0].width as usize - 2 - title.len(); // NOTE: -2 for the border @@ -165,20 +162,20 @@ impl TaskView { task.location().to_string() }; - overview.push(Spans::from(vec![bold(title), Span::raw(location)])); + overview.push(Line::from(vec![bold(title), Span::raw(location)])); let total = task.total(now); - let dur_percent = |name: &'static str, amt: Duration| -> Spans { + let dur_percent = |name: &'static str, amt: Duration| -> Line { let percent = amt.as_secs_f64().percent_of(total.as_secs_f64()); - Spans::from(vec![ + Line::from(vec![ bold(name), styles.time_units(amt, view::DUR_LIST_PRECISION, None), Span::from(format!(" ({:.2}%)", percent)), ]) }; - overview.push(Spans::from(vec![ + overview.push(Line::from(vec![ bold("Total Time: "), styles.time_units(total, view::DUR_LIST_PRECISION, None), ])); @@ -186,7 +183,7 @@ impl TaskView { overview.push(dur_percent("Scheduled: ", task.scheduled(now))); overview.push(dur_percent("Idle: ", task.idle(now))); - let mut waker_stats = vec![Spans::from(vec![ + let mut waker_stats = vec![Line::from(vec![ bold("Current wakers: "), Span::from(format!("{} (", task.waker_count())), bold("clones: "), @@ -209,10 +206,10 @@ impl TaskView { wakeups.push(Span::raw(" ago")); } - waker_stats.push(Spans::from(wakeups)); + waker_stats.push(Line::from(wakeups)); if task.self_wakes() > 0 { - waker_stats.push(Spans::from(vec![ + waker_stats.push(Line::from(vec![ bold("Self Wakes: "), Span::from(format!( "{} times ({}%)", @@ -223,7 +220,7 @@ impl TaskView { } let mut fields = Text::default(); - fields.extend(task.formatted_fields().iter().cloned().map(Spans::from)); + fields.extend(task.formatted_fields().iter().cloned().map(Line::from)); if let Some(warnings_area) = warnings_area { let warnings = List::new(warnings).block(styles.border_block().title("Warnings")); diff --git a/tokio-console/src/view/tasks.rs b/tokio-console/src/view/tasks.rs index d6d057b24..15e8f252c 100644 --- a/tokio-console/src/view/tasks.rs +++ b/tokio-console/src/view/tasks.rs @@ -13,7 +13,7 @@ use crate::{ use ratatui::{ layout, style::{self, Color, Style}, - text::{Span, Spans, Text}, + text::{Line, Span, Text}, widgets::{self, Cell, ListItem, Row, Table}, }; @@ -45,10 +45,10 @@ impl TableList<12> for TasksTable { Self::HEADER[11].len() + 1, ]; - fn render( + fn render( table_list_state: &mut TableListState, styles: &view::Styles, - frame: &mut ratatui::terminal::Frame, + frame: &mut ratatui::terminal::Frame, area: layout::Rect, state: &mut State, _: Self::Context, @@ -112,7 +112,7 @@ impl TableList<12> for TasksTable { let warnings = if n_warnings > 0 { let n_warnings = n_warnings.to_string(); warn_width.update_len(n_warnings.len() + 2); // add 2 for the warning icon + whitespace - Cell::from(Spans::from(vec![ + Cell::from(Line::from(vec![ styles.warning_narrow(), Span::from(n_warnings), ])) @@ -136,7 +136,7 @@ impl TableList<12> for TasksTable { Cell::from(polls_width.update_str(task.total_polls().to_string())), Cell::from(kind_width.update_str(task.kind()).to_owned()), Cell::from(location_width.update_str(task.location()).to_owned()), - Cell::from(Spans::from( + Cell::from(Line::from( task.formatted_fields() .iter() .flatten() @@ -173,9 +173,9 @@ impl TableList<12> for TasksTable { .style(header_style); let table = if table_list_state.sort_descending { - Table::new(rows) + Table::default().rows(rows) } else { - Table::new(rows.rev()) + Table::default().rows(rows.rev()) }; let block = styles.border_block().title(vec![ @@ -201,7 +201,7 @@ impl TableList<12> for TasksTable { .tasks_state() .warnings() .map(|warning| { - ListItem::new(Text::from(Spans::from(vec![ + ListItem::new(Text::from(Line::from(vec![ styles.warning_wide(), // TODO(eliza): it would be nice to handle singular vs plural... Span::from(format!("{} {}", warning.count(), warning.summary())), @@ -275,7 +275,7 @@ impl TableList<12> for TasksTable { if let Some(area) = warnings_area { let block = styles .border_block() - .title(Spans::from(vec![bold("Warnings")])); + .title(Line::from(vec![bold("Warnings")])); frame.render_widget(widgets::List::new(warnings).block(block), area); } diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index adac3529e..942416d42 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -3,7 +3,7 @@ name = "xtask" version = "0.1.0" license = "MIT" edition = "2021" -rust-version = "1.64.0" +rust-version = "1.74.0" publish = false [dependencies]