[go: up one dir, main page]

Struct Span

Source
pub struct Span<'a> {
    pub style: Style,
    pub content: Cow<'a, str>,
}
Expand description

Represents a part of a line that is contiguous and where all characters share the same style.

A Span is the smallest unit of text that can be styled. It is usually combined in the Line type to represent a line of text where each Span may have a different style.

§Constructor Methods

  • Span::default creates an span with empty content and the default style.
  • Span::raw creates an span with the specified content and the default style.
  • Span::styled creates an span with the specified content and style.

§Setter Methods

These methods are fluent setters. They return a new Span with the specified property set.

§Other Methods

§Examples

A Span with style set to Style::default() can be created from a &str, a String, or any type convertible to Cow<str>.

use ratatui::text::Span;

let span = Span::raw("test content");
let span = Span::raw(String::from("test content"));
let span = Span::from("test content");
let span = Span::from(String::from("test content"));
let span: Span = "test content".into();
let span: Span = String::from("test content").into();

Styled spans can be created using Span::styled or by converting strings using methods from the Stylize trait.

use ratatui::{
    style::{Style, Stylize},
    text::Span,
};

let span = Span::styled("test content", Style::new().green());
let span = Span::styled(String::from("test content"), Style::new().green());

// using Stylize trait shortcuts
let span = "test content".green();
let span = String::from("test content").green();

Span implements the Styled trait, which allows it to be styled using the shortcut methods defined in the Stylize trait.

use ratatui::{style::Stylize, text::Span};

let span = Span::raw("test content").green().on_yellow().italic();
let span = Span::raw(String::from("test content"))
    .green()
    .on_yellow()
    .italic();

Span implements the Widget trait, which allows it to be rendered to a Buffer. Usually apps will use the Paragraph widget instead of rendering Span directly, as it handles text wrapping and alignment for you.

use ratatui::{style::Stylize, Frame};

frame.render_widget("test content".green().on_yellow().italic(), frame.area());

Fields§

§style: Style

The style of the span.

§content: Cow<'a, str>

The content of the span as a Clone-on-write string.

Implementations§

Source§

impl<'a> Span<'a>

Source

pub fn raw<T>(content: T) -> Self
where T: Into<Cow<'a, str>>,

Create a span with the default style.

§Examples
use ratatui::text::Span;

Span::raw("test content");
Span::raw(String::from("test content"));
Examples found in repository?
examples/chart.rs (line 138)
132    fn render_animated_chart(&self, frame: &mut Frame, area: Rect) {
133        let x_labels = vec![
134            Span::styled(
135                format!("{}", self.window[0]),
136                Style::default().add_modifier(Modifier::BOLD),
137            ),
138            Span::raw(format!("{}", (self.window[0] + self.window[1]) / 2.0)),
139            Span::styled(
140                format!("{}", self.window[1]),
141                Style::default().add_modifier(Modifier::BOLD),
142            ),
143        ];
144        let datasets = vec![
145            Dataset::default()
146                .name("data2")
147                .marker(symbols::Marker::Dot)
148                .style(Style::default().fg(Color::Cyan))
149                .data(&self.data1),
150            Dataset::default()
151                .name("data3")
152                .marker(symbols::Marker::Braille)
153                .style(Style::default().fg(Color::Yellow))
154                .data(&self.data2),
155        ];
156
157        let chart = Chart::new(datasets)
158            .block(Block::bordered())
159            .x_axis(
160                Axis::default()
161                    .title("X Axis")
162                    .style(Style::default().fg(Color::Gray))
163                    .labels(x_labels)
164                    .bounds(self.window),
165            )
166            .y_axis(
167                Axis::default()
168                    .title("Y Axis")
169                    .style(Style::default().fg(Color::Gray))
170                    .labels(["-20".bold(), "0".into(), "20".bold()])
171                    .bounds([-20.0, 20.0]),
172            );
173
174        frame.render_widget(chart, area);
175    }
More examples
Hide additional examples
examples/inline.rs (line 257)
231fn draw(frame: &mut Frame, downloads: &Downloads) {
232    let area = frame.area();
233
234    let block = Block::new().title(Line::from("Progress").centered());
235    frame.render_widget(block, area);
236
237    let vertical = Layout::vertical([Constraint::Length(2), Constraint::Length(4)]).margin(1);
238    let horizontal = Layout::horizontal([Constraint::Percentage(20), Constraint::Percentage(80)]);
239    let [progress_area, main] = vertical.areas(area);
240    let [list_area, gauge_area] = horizontal.areas(main);
241
242    // total progress
243    let done = NUM_DOWNLOADS - downloads.pending.len() - downloads.in_progress.len();
244    #[allow(clippy::cast_precision_loss)]
245    let progress = LineGauge::default()
246        .filled_style(Style::default().fg(Color::Blue))
247        .label(format!("{done}/{NUM_DOWNLOADS}"))
248        .ratio(done as f64 / NUM_DOWNLOADS as f64);
249    frame.render_widget(progress, progress_area);
250
251    // in progress downloads
252    let items: Vec<ListItem> = downloads
253        .in_progress
254        .values()
255        .map(|download| {
256            ListItem::new(Line::from(vec![
257                Span::raw(symbols::DOT),
258                Span::styled(
259                    format!(" download {:>2}", download.id),
260                    Style::default()
261                        .fg(Color::LightGreen)
262                        .add_modifier(Modifier::BOLD),
263                ),
264                Span::raw(format!(
265                    " ({}ms)",
266                    download.started_at.elapsed().as_millis()
267                )),
268            ]))
269        })
270        .collect();
271    let list = List::new(items);
272    frame.render_widget(list, list_area);
273
274    #[allow(clippy::cast_possible_truncation)]
275    for (i, (_, download)) in downloads.in_progress.iter().enumerate() {
276        let gauge = Gauge::default()
277            .gauge_style(Style::default().fg(Color::Yellow))
278            .ratio(download.progress / 100.0);
279        if gauge_area.top().saturating_add(i as u16) > area.bottom() {
280            continue;
281        }
282        frame.render_widget(
283            gauge,
284            Rect {
285                x: gauge_area.left(),
286                y: gauge_area.top().saturating_add(i as u16),
287                width: gauge_area.width,
288                height: 1,
289            },
290        );
291    }
292}
examples/user_input.rs (line 231)
169    fn draw(&self, frame: &mut Frame) {
170        let vertical = Layout::vertical([
171            Constraint::Length(1),
172            Constraint::Length(3),
173            Constraint::Min(1),
174        ]);
175        let [help_area, input_area, messages_area] = vertical.areas(frame.area());
176
177        let (msg, style) = match self.input_mode {
178            InputMode::Normal => (
179                vec![
180                    "Press ".into(),
181                    "q".bold(),
182                    " to exit, ".into(),
183                    "e".bold(),
184                    " to start editing.".bold(),
185                ],
186                Style::default().add_modifier(Modifier::RAPID_BLINK),
187            ),
188            InputMode::Editing => (
189                vec![
190                    "Press ".into(),
191                    "Esc".bold(),
192                    " to stop editing, ".into(),
193                    "Enter".bold(),
194                    " to record the message".into(),
195                ],
196                Style::default(),
197            ),
198        };
199        let text = Text::from(Line::from(msg)).patch_style(style);
200        let help_message = Paragraph::new(text);
201        frame.render_widget(help_message, help_area);
202
203        let input = Paragraph::new(self.input.as_str())
204            .style(match self.input_mode {
205                InputMode::Normal => Style::default(),
206                InputMode::Editing => Style::default().fg(Color::Yellow),
207            })
208            .block(Block::bordered().title("Input"));
209        frame.render_widget(input, input_area);
210        match self.input_mode {
211            // Hide the cursor. `Frame` does this by default, so we don't need to do anything here
212            InputMode::Normal => {}
213
214            // Make the cursor visible and ask ratatui to put it at the specified coordinates after
215            // rendering
216            #[allow(clippy::cast_possible_truncation)]
217            InputMode::Editing => frame.set_cursor_position(Position::new(
218                // Draw the cursor at the current position in the input field.
219                // This position is can be controlled via the left and right arrow key
220                input_area.x + self.character_index as u16 + 1,
221                // Move one line down, from the border to the input line
222                input_area.y + 1,
223            )),
224        }
225
226        let messages: Vec<ListItem> = self
227            .messages
228            .iter()
229            .enumerate()
230            .map(|(i, m)| {
231                let content = Line::from(Span::raw(format!("{i}: {m}")));
232                ListItem::new(content)
233            })
234            .collect();
235        let messages = List::new(messages).block(Block::bordered().title("Messages"));
236        frame.render_widget(messages, messages_area);
237    }
examples/scrollbar.rs (line 118)
92    fn draw(&mut self, frame: &mut Frame) {
93        let area = frame.area();
94
95        // Words made "loooong" to demonstrate line breaking.
96        let s =
97            "Veeeeeeeeeeeeeeeery    loooooooooooooooooong   striiiiiiiiiiiiiiiiiiiiiiiiiing.   ";
98        let mut long_line = s.repeat(usize::from(area.width) / s.len() + 4);
99        long_line.push('\n');
100
101        let chunks = Layout::vertical([
102            Constraint::Min(1),
103            Constraint::Percentage(25),
104            Constraint::Percentage(25),
105            Constraint::Percentage(25),
106            Constraint::Percentage(25),
107        ])
108        .split(area);
109
110        let text = vec![
111            Line::from("This is a line "),
112            Line::from("This is a line   ".red()),
113            Line::from("This is a line".on_dark_gray()),
114            Line::from("This is a longer line".crossed_out()),
115            Line::from(long_line.clone()),
116            Line::from("This is a line".reset()),
117            Line::from(vec![
118                Span::raw("Masked text: "),
119                Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
120            ]),
121            Line::from("This is a line "),
122            Line::from("This is a line   ".red()),
123            Line::from("This is a line".on_dark_gray()),
124            Line::from("This is a longer line".crossed_out()),
125            Line::from(long_line.clone()),
126            Line::from("This is a line".reset()),
127            Line::from(vec![
128                Span::raw("Masked text: "),
129                Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
130            ]),
131        ];
132        self.vertical_scroll_state = self.vertical_scroll_state.content_length(text.len());
133        self.horizontal_scroll_state = self.horizontal_scroll_state.content_length(long_line.len());
134
135        let create_block = |title: &'static str| Block::bordered().gray().title(title.bold());
136
137        let title = Block::new()
138            .title_alignment(Alignment::Center)
139            .title("Use h j k l or ◄ ▲ ▼ ► to scroll ".bold());
140        frame.render_widget(title, chunks[0]);
141
142        let paragraph = Paragraph::new(text.clone())
143            .gray()
144            .block(create_block("Vertical scrollbar with arrows"))
145            .scroll((self.vertical_scroll as u16, 0));
146        frame.render_widget(paragraph, chunks[1]);
147        frame.render_stateful_widget(
148            Scrollbar::new(ScrollbarOrientation::VerticalRight)
149                .begin_symbol(Some("↑"))
150                .end_symbol(Some("↓")),
151            chunks[1],
152            &mut self.vertical_scroll_state,
153        );
154
155        let paragraph = Paragraph::new(text.clone())
156            .gray()
157            .block(create_block(
158                "Vertical scrollbar without arrows, without track symbol and mirrored",
159            ))
160            .scroll((self.vertical_scroll as u16, 0));
161        frame.render_widget(paragraph, chunks[2]);
162        frame.render_stateful_widget(
163            Scrollbar::new(ScrollbarOrientation::VerticalLeft)
164                .symbols(scrollbar::VERTICAL)
165                .begin_symbol(None)
166                .track_symbol(None)
167                .end_symbol(None),
168            chunks[2].inner(Margin {
169                vertical: 1,
170                horizontal: 0,
171            }),
172            &mut self.vertical_scroll_state,
173        );
174
175        let paragraph = Paragraph::new(text.clone())
176            .gray()
177            .block(create_block(
178                "Horizontal scrollbar with only begin arrow & custom thumb symbol",
179            ))
180            .scroll((0, self.horizontal_scroll as u16));
181        frame.render_widget(paragraph, chunks[3]);
182        frame.render_stateful_widget(
183            Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
184                .thumb_symbol("🬋")
185                .end_symbol(None),
186            chunks[3].inner(Margin {
187                vertical: 0,
188                horizontal: 1,
189            }),
190            &mut self.horizontal_scroll_state,
191        );
192
193        let paragraph = Paragraph::new(text.clone())
194            .gray()
195            .block(create_block(
196                "Horizontal scrollbar without arrows & custom thumb and track symbol",
197            ))
198            .scroll((0, self.horizontal_scroll as u16));
199        frame.render_widget(paragraph, chunks[4]);
200        frame.render_stateful_widget(
201            Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
202                .thumb_symbol("░")
203                .track_symbol(Some("─")),
204            chunks[4].inner(Margin {
205                vertical: 0,
206                horizontal: 1,
207            }),
208            &mut self.horizontal_scroll_state,
209        );
210    }
Source

pub fn styled<T, S>(content: T, style: S) -> Self
where T: Into<Cow<'a, str>>, S: Into<Style>,

Create a span with the specified style.

content accepts any type that is convertible to Cow<str> (e.g. &str, String, &String, etc.).

style accepts any type that is convertible to Style (e.g. Style, Color, or your own type that implements Into<Style>).

§Examples
use ratatui::{
    style::{Style, Stylize},
    text::Span,
};

let style = Style::new().yellow().on_green().italic();
Span::styled("test content", style);
Span::styled(String::from("test content"), style);
Examples found in repository?
examples/gauge.rs (lines 162-165)
160    fn render_gauge2(&self, area: Rect, buf: &mut Buffer) {
161        let title = title_block("Gauge with ratio and custom label");
162        let label = Span::styled(
163            format!("{:.1}/100", self.progress2),
164            Style::new().italic().bold().fg(CUSTOM_LABEL_COLOR),
165        );
166        Gauge::default()
167            .block(title)
168            .gauge_style(GAUGE2_COLOR)
169            .ratio(self.progress2 / 100.0)
170            .label(label)
171            .render(area, buf);
172    }
More examples
Hide additional examples
examples/demo2/app.rs (line 161)
157    fn render_title_bar(&self, area: Rect, buf: &mut Buffer) {
158        let layout = Layout::horizontal([Constraint::Min(0), Constraint::Length(43)]);
159        let [title, tabs] = layout.areas(area);
160
161        Span::styled("Ratatui", THEME.app_title).render(title, buf);
162        let titles = Tab::iter().map(Tab::title);
163        Tabs::new(titles)
164            .style(THEME.tabs)
165            .highlight_style(THEME.tabs_selected)
166            .select(self.tab as usize)
167            .divider("")
168            .padding("", "")
169            .render(tabs, buf);
170    }
171
172    fn render_selected_tab(&self, area: Rect, buf: &mut Buffer) {
173        match self.tab {
174            Tab::About => self.about_tab.render(area, buf),
175            Tab::Recipe => self.recipe_tab.render(area, buf),
176            Tab::Email => self.email_tab.render(area, buf),
177            Tab::Traceroute => self.traceroute_tab.render(area, buf),
178            Tab::Weather => self.weather_tab.render(area, buf),
179        };
180    }
181
182    fn render_bottom_bar(area: Rect, buf: &mut Buffer) {
183        let keys = [
184            ("H/←", "Left"),
185            ("L/→", "Right"),
186            ("K/↑", "Up"),
187            ("J/↓", "Down"),
188            ("D/Del", "Destroy"),
189            ("Q/Esc", "Quit"),
190        ];
191        let spans = keys
192            .iter()
193            .flat_map(|(key, desc)| {
194                let key = Span::styled(format!(" {key} "), THEME.key_binding.key);
195                let desc = Span::styled(format!(" {desc} "), THEME.key_binding.description);
196                [key, desc]
197            })
198            .collect_vec();
199        Line::from(spans)
200            .centered()
201            .style((Color::Indexed(236), Color::Indexed(232)))
202            .render(area, buf);
203    }
examples/paragraph.rs (line 150)
128fn create_lines(area: Rect) -> Vec<Line<'static>> {
129    let short_line = "A long line to demonstrate line wrapping. ";
130    let long_line = short_line.repeat(usize::from(area.width) / short_line.len() + 4);
131    let mut styled_spans = vec![];
132    for span in [
133        "Styled".blue(),
134        "Spans".red().on_white(),
135        "Bold".bold(),
136        "Italic".italic(),
137        "Underlined".underlined(),
138        "Strikethrough".crossed_out(),
139    ] {
140        styled_spans.push(span);
141        styled_spans.push(" ".into());
142    }
143    vec![
144        Line::raw("Unstyled Line"),
145        Line::raw("Styled Line").black().on_red().bold().italic(),
146        Line::from(styled_spans),
147        Line::from(long_line.green().italic()),
148        Line::from_iter([
149            "Masked text: ".into(),
150            Span::styled(Masked::new("my secret password", '*'), Color::Red),
151        ]),
152    ]
153}
examples/chart.rs (lines 134-137)
132    fn render_animated_chart(&self, frame: &mut Frame, area: Rect) {
133        let x_labels = vec![
134            Span::styled(
135                format!("{}", self.window[0]),
136                Style::default().add_modifier(Modifier::BOLD),
137            ),
138            Span::raw(format!("{}", (self.window[0] + self.window[1]) / 2.0)),
139            Span::styled(
140                format!("{}", self.window[1]),
141                Style::default().add_modifier(Modifier::BOLD),
142            ),
143        ];
144        let datasets = vec![
145            Dataset::default()
146                .name("data2")
147                .marker(symbols::Marker::Dot)
148                .style(Style::default().fg(Color::Cyan))
149                .data(&self.data1),
150            Dataset::default()
151                .name("data3")
152                .marker(symbols::Marker::Braille)
153                .style(Style::default().fg(Color::Yellow))
154                .data(&self.data2),
155        ];
156
157        let chart = Chart::new(datasets)
158            .block(Block::bordered())
159            .x_axis(
160                Axis::default()
161                    .title("X Axis")
162                    .style(Style::default().fg(Color::Gray))
163                    .labels(x_labels)
164                    .bounds(self.window),
165            )
166            .y_axis(
167                Axis::default()
168                    .title("Y Axis")
169                    .style(Style::default().fg(Color::Gray))
170                    .labels(["-20".bold(), "0".into(), "20".bold()])
171                    .bounds([-20.0, 20.0]),
172            );
173
174        frame.render_widget(chart, area);
175    }
examples/inline.rs (lines 203-206)
170fn run(
171    terminal: &mut Terminal<impl Backend>,
172    workers: Vec<Worker>,
173    mut downloads: Downloads,
174    rx: mpsc::Receiver<Event>,
175) -> Result<()> {
176    let mut redraw = true;
177    loop {
178        if redraw {
179            terminal.draw(|frame| draw(frame, &downloads))?;
180        }
181        redraw = true;
182
183        match rx.recv()? {
184            Event::Input(event) => {
185                if event.code == event::KeyCode::Char('q') {
186                    break;
187                }
188            }
189            Event::Resize => {
190                terminal.autoresize()?;
191            }
192            Event::Tick => {}
193            Event::DownloadUpdate(worker_id, _download_id, progress) => {
194                let download = downloads.in_progress.get_mut(&worker_id).unwrap();
195                download.progress = progress;
196                redraw = false;
197            }
198            Event::DownloadDone(worker_id, download_id) => {
199                let download = downloads.in_progress.remove(&worker_id).unwrap();
200                terminal.insert_before(1, |buf| {
201                    Paragraph::new(Line::from(vec![
202                        Span::from("Finished "),
203                        Span::styled(
204                            format!("download {download_id}"),
205                            Style::default().add_modifier(Modifier::BOLD),
206                        ),
207                        Span::from(format!(
208                            " in {}ms",
209                            download.started_at.elapsed().as_millis()
210                        )),
211                    ]))
212                    .render(buf.area, buf);
213                })?;
214                match downloads.next(worker_id) {
215                    Some(d) => workers[worker_id].tx.send(d).unwrap(),
216                    None => {
217                        if downloads.in_progress.is_empty() {
218                            terminal.insert_before(1, |buf| {
219                                Paragraph::new("Done !").render(buf.area, buf);
220                            })?;
221                            break;
222                        }
223                    }
224                };
225            }
226        };
227    }
228    Ok(())
229}
230
231fn draw(frame: &mut Frame, downloads: &Downloads) {
232    let area = frame.area();
233
234    let block = Block::new().title(Line::from("Progress").centered());
235    frame.render_widget(block, area);
236
237    let vertical = Layout::vertical([Constraint::Length(2), Constraint::Length(4)]).margin(1);
238    let horizontal = Layout::horizontal([Constraint::Percentage(20), Constraint::Percentage(80)]);
239    let [progress_area, main] = vertical.areas(area);
240    let [list_area, gauge_area] = horizontal.areas(main);
241
242    // total progress
243    let done = NUM_DOWNLOADS - downloads.pending.len() - downloads.in_progress.len();
244    #[allow(clippy::cast_precision_loss)]
245    let progress = LineGauge::default()
246        .filled_style(Style::default().fg(Color::Blue))
247        .label(format!("{done}/{NUM_DOWNLOADS}"))
248        .ratio(done as f64 / NUM_DOWNLOADS as f64);
249    frame.render_widget(progress, progress_area);
250
251    // in progress downloads
252    let items: Vec<ListItem> = downloads
253        .in_progress
254        .values()
255        .map(|download| {
256            ListItem::new(Line::from(vec![
257                Span::raw(symbols::DOT),
258                Span::styled(
259                    format!(" download {:>2}", download.id),
260                    Style::default()
261                        .fg(Color::LightGreen)
262                        .add_modifier(Modifier::BOLD),
263                ),
264                Span::raw(format!(
265                    " ({}ms)",
266                    download.started_at.elapsed().as_millis()
267                )),
268            ]))
269        })
270        .collect();
271    let list = List::new(items);
272    frame.render_widget(list, list_area);
273
274    #[allow(clippy::cast_possible_truncation)]
275    for (i, (_, download)) in downloads.in_progress.iter().enumerate() {
276        let gauge = Gauge::default()
277            .gauge_style(Style::default().fg(Color::Yellow))
278            .ratio(download.progress / 100.0);
279        if gauge_area.top().saturating_add(i as u16) > area.bottom() {
280            continue;
281        }
282        frame.render_widget(
283            gauge,
284            Rect {
285                x: gauge_area.left(),
286                y: gauge_area.top().saturating_add(i as u16),
287                width: gauge_area.width,
288                height: 1,
289            },
290        );
291    }
292}
examples/scrollbar.rs (line 119)
92    fn draw(&mut self, frame: &mut Frame) {
93        let area = frame.area();
94
95        // Words made "loooong" to demonstrate line breaking.
96        let s =
97            "Veeeeeeeeeeeeeeeery    loooooooooooooooooong   striiiiiiiiiiiiiiiiiiiiiiiiiing.   ";
98        let mut long_line = s.repeat(usize::from(area.width) / s.len() + 4);
99        long_line.push('\n');
100
101        let chunks = Layout::vertical([
102            Constraint::Min(1),
103            Constraint::Percentage(25),
104            Constraint::Percentage(25),
105            Constraint::Percentage(25),
106            Constraint::Percentage(25),
107        ])
108        .split(area);
109
110        let text = vec![
111            Line::from("This is a line "),
112            Line::from("This is a line   ".red()),
113            Line::from("This is a line".on_dark_gray()),
114            Line::from("This is a longer line".crossed_out()),
115            Line::from(long_line.clone()),
116            Line::from("This is a line".reset()),
117            Line::from(vec![
118                Span::raw("Masked text: "),
119                Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
120            ]),
121            Line::from("This is a line "),
122            Line::from("This is a line   ".red()),
123            Line::from("This is a line".on_dark_gray()),
124            Line::from("This is a longer line".crossed_out()),
125            Line::from(long_line.clone()),
126            Line::from("This is a line".reset()),
127            Line::from(vec![
128                Span::raw("Masked text: "),
129                Span::styled(Masked::new("password", '*'), Style::new().fg(Color::Red)),
130            ]),
131        ];
132        self.vertical_scroll_state = self.vertical_scroll_state.content_length(text.len());
133        self.horizontal_scroll_state = self.horizontal_scroll_state.content_length(long_line.len());
134
135        let create_block = |title: &'static str| Block::bordered().gray().title(title.bold());
136
137        let title = Block::new()
138            .title_alignment(Alignment::Center)
139            .title("Use h j k l or ◄ ▲ ▼ ► to scroll ".bold());
140        frame.render_widget(title, chunks[0]);
141
142        let paragraph = Paragraph::new(text.clone())
143            .gray()
144            .block(create_block("Vertical scrollbar with arrows"))
145            .scroll((self.vertical_scroll as u16, 0));
146        frame.render_widget(paragraph, chunks[1]);
147        frame.render_stateful_widget(
148            Scrollbar::new(ScrollbarOrientation::VerticalRight)
149                .begin_symbol(Some("↑"))
150                .end_symbol(Some("↓")),
151            chunks[1],
152            &mut self.vertical_scroll_state,
153        );
154
155        let paragraph = Paragraph::new(text.clone())
156            .gray()
157            .block(create_block(
158                "Vertical scrollbar without arrows, without track symbol and mirrored",
159            ))
160            .scroll((self.vertical_scroll as u16, 0));
161        frame.render_widget(paragraph, chunks[2]);
162        frame.render_stateful_widget(
163            Scrollbar::new(ScrollbarOrientation::VerticalLeft)
164                .symbols(scrollbar::VERTICAL)
165                .begin_symbol(None)
166                .track_symbol(None)
167                .end_symbol(None),
168            chunks[2].inner(Margin {
169                vertical: 1,
170                horizontal: 0,
171            }),
172            &mut self.vertical_scroll_state,
173        );
174
175        let paragraph = Paragraph::new(text.clone())
176            .gray()
177            .block(create_block(
178                "Horizontal scrollbar with only begin arrow & custom thumb symbol",
179            ))
180            .scroll((0, self.horizontal_scroll as u16));
181        frame.render_widget(paragraph, chunks[3]);
182        frame.render_stateful_widget(
183            Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
184                .thumb_symbol("🬋")
185                .end_symbol(None),
186            chunks[3].inner(Margin {
187                vertical: 0,
188                horizontal: 1,
189            }),
190            &mut self.horizontal_scroll_state,
191        );
192
193        let paragraph = Paragraph::new(text.clone())
194            .gray()
195            .block(create_block(
196                "Horizontal scrollbar without arrows & custom thumb and track symbol",
197            ))
198            .scroll((0, self.horizontal_scroll as u16));
199        frame.render_widget(paragraph, chunks[4]);
200        frame.render_stateful_widget(
201            Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
202                .thumb_symbol("░")
203                .track_symbol(Some("─")),
204            chunks[4].inner(Margin {
205                vertical: 0,
206                horizontal: 1,
207            }),
208            &mut self.horizontal_scroll_state,
209        );
210    }
Source

pub fn content<T>(self, content: T) -> Self
where T: Into<Cow<'a, str>>,

Sets the content of the span.

This is a fluent setter method which must be chained or used as it consumes self

Accepts any type that can be converted to Cow<str> (e.g. &str, String, &String, etc.).

§Examples
use ratatui::text::Span;

let mut span = Span::default().content("content");
Source

pub fn style<S: Into<Style>>(self, style: S) -> Self

Sets the style of the span.

This is a fluent setter method which must be chained or used as it consumes self

In contrast to Span::patch_style, this method replaces the style of the span instead of patching it.

style accepts any type that is convertible to Style (e.g. Style, Color, or your own type that implements Into<Style>).

§Examples
use ratatui::{
    style::{Style, Stylize},
    text::Span,
};

let mut span = Span::default().style(Style::new().green());
Source

pub fn patch_style<S: Into<Style>>(self, style: S) -> Self

Patches the style of the Span, adding modifiers from the given style.

style accepts any type that is convertible to Style (e.g. Style, Color, or your own type that implements Into<Style>).

This is a fluent setter method which must be chained or used as it consumes self

§Example
use ratatui::{
    style::{Style, Stylize},
    text::Span,
};

let span = Span::styled("test content", Style::new().green().italic())
    .patch_style(Style::new().red().on_yellow().bold());
assert_eq!(span.style, Style::new().red().on_yellow().italic().bold());
Source

pub fn reset_style(self) -> Self

Resets the style of the Span.

This is Equivalent to calling patch_style(Style::reset()).

This is a fluent setter method which must be chained or used as it consumes self

§Example
use ratatui::{
    style::{Style, Stylize},
    text::Span,
};

let span = Span::styled(
    "Test Content",
    Style::new().dark_gray().on_yellow().italic(),
)
.reset_style();
assert_eq!(span.style, Style::reset());
Source

pub fn width(&self) -> usize

Returns the unicode width of the content held by this span.

Source

pub fn styled_graphemes<S: Into<Style>>( &'a self, base_style: S, ) -> impl Iterator<Item = StyledGrapheme<'a>>

Returns an iterator over the graphemes held by this span.

base_style is the Style that will be patched with the Span’s style to get the resulting Style.

base_style accepts any type that is convertible to Style (e.g. Style, Color, or your own type that implements Into<Style>).

§Example
use std::iter::Iterator;

use ratatui::{
    style::{Style, Stylize},
    text::{Span, StyledGrapheme},
};

let span = Span::styled("Test", Style::new().green().italic());
let style = Style::new().red().on_yellow();
assert_eq!(
    span.styled_graphemes(style)
        .collect::<Vec<StyledGrapheme>>(),
    vec![
        StyledGrapheme::new("T", Style::new().green().on_yellow().italic()),
        StyledGrapheme::new("e", Style::new().green().on_yellow().italic()),
        StyledGrapheme::new("s", Style::new().green().on_yellow().italic()),
        StyledGrapheme::new("t", Style::new().green().on_yellow().italic()),
    ],
);
Source

pub fn into_left_aligned_line(self) -> Line<'a>

Converts this Span into a left-aligned Line

§Example
use ratatui::style::Stylize;

let line = "Test Content".green().italic().into_left_aligned_line();
Source

pub fn to_left_aligned_line(self) -> Line<'a>

👎Deprecated: use into_left_aligned_line
Source

pub fn into_centered_line(self) -> Line<'a>

Converts this Span into a center-aligned Line

§Example
use ratatui::style::Stylize;

let line = "Test Content".green().italic().into_centered_line();
Examples found in repository?
examples/paragraph.rs (line 124)
121fn title_block(title: &str) -> Block {
122    Block::bordered()
123        .gray()
124        .title(title.bold().into_centered_line())
125}
More examples
Hide additional examples
examples/constraint-explorer.rs (line 279)
277    fn header() -> impl Widget {
278        let text = "Constraint Explorer";
279        text.bold().fg(Self::HEADER_COLOR).into_centered_line()
280    }
281
282    fn instructions() -> impl Widget {
283        let text = "◄ ►: select, ▲ ▼: edit, 1-6: swap, a: add, x: delete, q: quit, + -: spacing";
284        Paragraph::new(text)
285            .fg(Self::TEXT_COLOR)
286            .centered()
287            .wrap(Wrap { trim: false })
288    }
289
290    fn swap_legend() -> impl Widget {
291        #[allow(unstable_name_collisions)]
292        Paragraph::new(
293            Line::from(
294                [
295                    ConstraintName::Min,
296                    ConstraintName::Max,
297                    ConstraintName::Length,
298                    ConstraintName::Percentage,
299                    ConstraintName::Ratio,
300                    ConstraintName::Fill,
301                ]
302                .iter()
303                .enumerate()
304                .map(|(i, name)| {
305                    format!("  {i}: {name}  ", i = i + 1)
306                        .fg(SLATE.c200)
307                        .bg(name.color())
308                })
309                .intersperse(Span::from(" "))
310                .collect_vec(),
311            )
312            .centered(),
313        )
314        .wrap(Wrap { trim: false })
315    }
316
317    /// A bar like `<----- 80 px (gap: 2 px) ----->`
318    ///
319    /// Only shows the gap when spacing is not zero
320    fn axis(&self, width: u16) -> impl Widget {
321        let label = if self.spacing != 0 {
322            format!("{} px (gap: {} px)", width, self.spacing)
323        } else {
324            format!("{width} px")
325        };
326        let bar_width = width.saturating_sub(2) as usize; // we want to `<` and `>` at the ends
327        let width_bar = format!("<{label:-^bar_width$}>");
328        Paragraph::new(width_bar).fg(Self::AXIS_COLOR).centered()
329    }
330
331    fn render_layout_blocks(&self, area: Rect, buf: &mut Buffer) {
332        let [user_constraints, area] = Layout::vertical([Length(3), Fill(1)])
333            .spacing(1)
334            .areas(area);
335
336        self.render_user_constraints_legend(user_constraints, buf);
337
338        let [start, center, end, space_around, space_between] =
339            Layout::vertical([Length(7); 5]).areas(area);
340
341        self.render_layout_block(Flex::Start, start, buf);
342        self.render_layout_block(Flex::Center, center, buf);
343        self.render_layout_block(Flex::End, end, buf);
344        self.render_layout_block(Flex::SpaceAround, space_around, buf);
345        self.render_layout_block(Flex::SpaceBetween, space_between, buf);
346    }
347
348    fn render_user_constraints_legend(&self, area: Rect, buf: &mut Buffer) {
349        let constraints = self.constraints.iter().map(|_| Constraint::Fill(1));
350        let blocks = Layout::horizontal(constraints).split(area);
351
352        for (i, (area, constraint)) in blocks.iter().zip(self.constraints.iter()).enumerate() {
353            let selected = self.selected_index == i;
354            ConstraintBlock::new(*constraint, selected, true).render(*area, buf);
355        }
356    }
357
358    fn render_layout_block(&self, flex: Flex, area: Rect, buf: &mut Buffer) {
359        let [label_area, axis_area, blocks_area] =
360            Layout::vertical([Length(1), Max(1), Length(4)]).areas(area);
361
362        if label_area.height > 0 {
363            format!("Flex::{flex:?}").bold().render(label_area, buf);
364        }
365
366        self.axis(area.width).render(axis_area, buf);
367
368        let (blocks, spacers) = Layout::horizontal(&self.constraints)
369            .flex(flex)
370            .spacing(self.spacing)
371            .split_with_spacers(blocks_area);
372
373        for (i, (area, constraint)) in blocks.iter().zip(self.constraints.iter()).enumerate() {
374            let selected = self.selected_index == i;
375            ConstraintBlock::new(*constraint, selected, false).render(*area, buf);
376        }
377
378        for area in spacers.iter() {
379            SpacerBlock.render(*area, buf);
380        }
381    }
382}
383
384impl Widget for ConstraintBlock {
385    fn render(self, area: Rect, buf: &mut Buffer) {
386        match area.height {
387            1 => self.render_1px(area, buf),
388            2 => self.render_2px(area, buf),
389            _ => self.render_4px(area, buf),
390        }
391    }
392}
393
394impl ConstraintBlock {
395    const TEXT_COLOR: Color = SLATE.c200;
396
397    const fn new(constraint: Constraint, selected: bool, legend: bool) -> Self {
398        Self {
399            constraint,
400            legend,
401            selected,
402        }
403    }
404
405    fn label(&self, width: u16) -> String {
406        let long_width = format!("{width} px");
407        let short_width = format!("{width}");
408        // border takes up 2 columns
409        let available_space = width.saturating_sub(2) as usize;
410        let width_label = if long_width.len() < available_space {
411            long_width
412        } else if short_width.len() < available_space {
413            short_width
414        } else {
415            String::new()
416        };
417        format!("{}\n{}", self.constraint, width_label)
418    }
419
420    fn render_1px(&self, area: Rect, buf: &mut Buffer) {
421        let lighter_color = ConstraintName::from(self.constraint).lighter_color();
422        let main_color = ConstraintName::from(self.constraint).color();
423        let selected_color = if self.selected {
424            lighter_color
425        } else {
426            main_color
427        };
428        Block::new()
429            .fg(Self::TEXT_COLOR)
430            .bg(selected_color)
431            .render(area, buf);
432    }
433
434    fn render_2px(&self, area: Rect, buf: &mut Buffer) {
435        let lighter_color = ConstraintName::from(self.constraint).lighter_color();
436        let main_color = ConstraintName::from(self.constraint).color();
437        let selected_color = if self.selected {
438            lighter_color
439        } else {
440            main_color
441        };
442        Block::bordered()
443            .border_set(symbols::border::QUADRANT_OUTSIDE)
444            .border_style(Style::reset().fg(selected_color).reversed())
445            .render(area, buf);
446    }
447
448    fn render_4px(&self, area: Rect, buf: &mut Buffer) {
449        let lighter_color = ConstraintName::from(self.constraint).lighter_color();
450        let main_color = ConstraintName::from(self.constraint).color();
451        let selected_color = if self.selected {
452            lighter_color
453        } else {
454            main_color
455        };
456        let color = if self.legend {
457            selected_color
458        } else {
459            main_color
460        };
461        let label = self.label(area.width);
462        let block = Block::bordered()
463            .border_set(symbols::border::QUADRANT_OUTSIDE)
464            .border_style(Style::reset().fg(color).reversed())
465            .fg(Self::TEXT_COLOR)
466            .bg(color);
467        Paragraph::new(label)
468            .centered()
469            .fg(Self::TEXT_COLOR)
470            .bg(color)
471            .block(block)
472            .render(area, buf);
473
474        if !self.legend {
475            let border_color = if self.selected {
476                lighter_color
477            } else {
478                main_color
479            };
480            if let Some(last_row) = area.rows().last() {
481                buf.set_style(last_row, border_color);
482            }
483        }
484    }
485}
486
487impl Widget for SpacerBlock {
488    fn render(self, area: Rect, buf: &mut Buffer) {
489        match area.height {
490            1 => (),
491            2 => Self::render_2px(area, buf),
492            3 => Self::render_3px(area, buf),
493            _ => Self::render_4px(area, buf),
494        }
495    }
496}
497
498impl SpacerBlock {
499    const TEXT_COLOR: Color = SLATE.c500;
500    const BORDER_COLOR: Color = SLATE.c600;
501
502    /// A block with a corner borders
503    fn block() -> impl Widget {
504        let corners_only = symbols::border::Set {
505            top_left: line::NORMAL.top_left,
506            top_right: line::NORMAL.top_right,
507            bottom_left: line::NORMAL.bottom_left,
508            bottom_right: line::NORMAL.bottom_right,
509            vertical_left: " ",
510            vertical_right: " ",
511            horizontal_top: " ",
512            horizontal_bottom: " ",
513        };
514        Block::bordered()
515            .border_set(corners_only)
516            .border_style(Self::BORDER_COLOR)
517    }
518
519    /// A vertical line used if there is not enough space to render the block
520    fn line() -> impl Widget {
521        Paragraph::new(Text::from(vec![
522            Line::from(""),
523            Line::from("│"),
524            Line::from("│"),
525            Line::from(""),
526        ]))
527        .style(Self::BORDER_COLOR)
528    }
529
530    /// A label that says "Spacer" if there is enough space
531    fn spacer_label(width: u16) -> impl Widget {
532        let label = if width >= 6 { "Spacer" } else { "" };
533        label.fg(Self::TEXT_COLOR).into_centered_line()
534    }
examples/barchart-grouped.rs (line 87)
82    fn draw(&self, frame: &mut Frame) {
83        use Constraint::{Fill, Length, Min};
84        let vertical = Layout::vertical([Length(1), Fill(1), Min(20)]).spacing(1);
85        let [title, top, bottom] = vertical.areas(frame.area());
86
87        frame.render_widget("Grouped Barchart".bold().into_centered_line(), title);
88        frame.render_widget(self.vertical_revenue_barchart(), top);
89        frame.render_widget(self.horizontal_revenue_barchart(), bottom);
90    }
examples/barchart.rs (line 76)
67    fn draw(&self, frame: &mut Frame) {
68        let [title, vertical, horizontal] = Layout::vertical([
69            Constraint::Length(1),
70            Constraint::Fill(1),
71            Constraint::Fill(1),
72        ])
73        .spacing(1)
74        .areas(frame.area());
75
76        frame.render_widget("Barchart".bold().into_centered_line(), title);
77        frame.render_widget(vertical_barchart(&self.temperatures), vertical);
78        frame.render_widget(horizontal_barchart(&self.temperatures), horizontal);
79    }
Source

pub fn to_centered_line(self) -> Line<'a>

👎Deprecated: use into_centered_line
Source

pub fn into_right_aligned_line(self) -> Line<'a>

Converts this Span into a right-aligned Line

§Example
use ratatui::style::Stylize;

let line = "Test Content".green().italic().into_right_aligned_line();
Source

pub fn to_right_aligned_line(self) -> Line<'a>

👎Deprecated: use into_right_aligned_line

Trait Implementations§

Source§

impl<'a> Add<Span<'a>> for Line<'a>

Adds a Span to a Line, returning a new Line with the Span added.

Source§

type Output = Line<'a>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Span<'a>) -> Self::Output

Performs the + operation. Read more
Source§

impl<'a> Add for Span<'a>

Source§

type Output = Line<'a>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Self) -> Self::Output

Performs the + operation. Read more
Source§

impl<'a> AddAssign<Span<'a>> for Line<'a>

Source§

fn add_assign(&mut self, rhs: Span<'a>)

Performs the += operation. Read more
Source§

impl<'a> Clone for Span<'a>

Source§

fn clone(&self) -> Span<'a>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Span<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Default for Span<'a>

Source§

fn default() -> Span<'a>

Returns the “default value” for a type. Read more
Source§

impl Display for Span<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Extend<Span<'a>> for Line<'a>

Source§

fn extend<T: IntoIterator<Item = Span<'a>>>(&mut self, iter: T)

Extends a collection with the contents of an iterator. Read more
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<'a> From<Span<'a>> for Line<'a>

Source§

fn from(span: Span<'a>) -> Self

Converts to this type from the input type.
Source§

impl<'a> From<Span<'a>> for Text<'a>

Source§

fn from(span: Span<'a>) -> Self

Converts to this type from the input type.
Source§

impl<'a, T> From<T> for Span<'a>
where T: Into<Cow<'a, str>>,

Source§

fn from(s: T) -> Self

Converts to this type from the input type.
Source§

impl<'a> Hash for Span<'a>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<'a> PartialEq for Span<'a>

Source§

fn eq(&self, other: &Span<'a>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a> Styled for Span<'a>

Source§

type Item = Span<'a>

Source§

fn style(&self) -> Style

Returns the style of the object.
Source§

fn set_style<S: Into<Style>>(self, style: S) -> Self::Item

Sets the style of the object. Read more
Source§

impl Widget for Span<'_>

Source§

fn render(self, area: Rect, buf: &mut Buffer)

Draws the current state of the widget in the given buffer. That is the only method required to implement a custom widget.
Source§

impl WidgetRef for Span<'_>

Source§

fn render_ref(&self, area: Rect, buf: &mut Buffer)

Available on crate feature unstable-widget-ref only.
Draws the current state of the widget in the given buffer. That is the only method required to implement a custom widget.
Source§

impl<'a> Eq for Span<'a>

Source§

impl<'a> StructuralPartialEq for Span<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Span<'a>

§

impl<'a> RefUnwindSafe for Span<'a>

§

impl<'a> Send for Span<'a>

§

impl<'a> Sync for Span<'a>

§

impl<'a> Unpin for Span<'a>

§

impl<'a> UnwindSafe for Span<'a>

Blanket Implementations§

Source§

impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for S
where T: Real + Zero + Arithmetics + Clone, Swp: WhitePoint<T>, Dwp: WhitePoint<T>, D: AdaptFrom<S, Swp, Dwp, T>,

Source§

fn adapt_into_using<M>(self, method: M) -> D
where M: TransformMatrix<T>,

Convert the source color to the destination color using the specified method.
Source§

fn adapt_into(self) -> D

Convert the source color to the destination color using the bradford method by default.
Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, C> ArraysFrom<C> for T
where C: IntoArrays<T>,

Source§

fn arrays_from(colors: C) -> T

Cast a collection of colors into a collection of arrays.
Source§

impl<T, C> ArraysInto<C> for T
where C: FromArrays<T>,

Source§

fn arrays_into(self) -> C

Cast this collection of arrays into a collection of colors.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for U
where T: FromCam16Unclamped<WpParam, U>,

Source§

type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T, C> ComponentsFrom<C> for T
where C: IntoComponents<T>,

Source§

fn components_from(colors: C) -> T

Cast a collection of colors into a collection of color components.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromAngle<T> for T

Source§

fn from_angle(angle: T) -> T

Performs a conversion from angle.
Source§

impl<T, U> FromStimulus<U> for T
where U: IntoStimulus<T>,

Source§

fn from_stimulus(other: U) -> T

Converts other into Self, while performing the appropriate scaling, rounding and clamping.
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> IntoAngle<U> for T
where U: FromAngle<T>,

Source§

fn into_angle(self) -> U

Performs a conversion into T.
Source§

impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for U
where T: Cam16FromUnclamped<WpParam, U>,

Source§

type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T, U> IntoColor<U> for T
where U: FromColor<T>,

Source§

fn into_color(self) -> U

Convert into T with values clamped to the color defined bounds Read more
Source§

impl<T, U> IntoColorUnclamped<U> for T
where U: FromColorUnclamped<T>,

Source§

fn into_color_unclamped(self) -> U

Convert into T. The resulting color might be invalid in its color space Read more
Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoStimulus<T> for T

Source§

fn into_stimulus(self) -> T

Converts self into T, while performing the appropriate scaling, rounding and clamping.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<'a, T, U> Stylize<'a, T> for U
where U: Styled<Item = T>,

Source§

fn bg<C>(self, color: C) -> T
where C: Into<Color>,

Source§

fn fg<C>(self, color: C) -> T
where C: Into<Color>,

Source§

fn add_modifier(self, modifier: Modifier) -> T

Source§

fn remove_modifier(self, modifier: Modifier) -> T

Source§

fn reset(self) -> T

Source§

fn black(self) -> T

Sets the foreground color to black.
Source§

fn on_black(self) -> T

Sets the background color to black.
Source§

fn red(self) -> T

Sets the foreground color to red.
Source§

fn on_red(self) -> T

Sets the background color to red.
Source§

fn green(self) -> T

Sets the foreground color to green.
Source§

fn on_green(self) -> T

Sets the background color to green.
Source§

fn yellow(self) -> T

Sets the foreground color to yellow.
Source§

fn on_yellow(self) -> T

Sets the background color to yellow.
Source§

fn blue(self) -> T

Sets the foreground color to blue.
Source§

fn on_blue(self) -> T

Sets the background color to blue.
Source§

fn magenta(self) -> T

Sets the foreground color to magenta.
Source§

fn on_magenta(self) -> T

Sets the background color to magenta.
Source§

fn cyan(self) -> T

Sets the foreground color to cyan.
Source§

fn on_cyan(self) -> T

Sets the background color to cyan.
Source§

fn gray(self) -> T

Sets the foreground color to gray.
Source§

fn on_gray(self) -> T

Sets the background color to gray.
Source§

fn dark_gray(self) -> T

Sets the foreground color to dark_gray.
Source§

fn on_dark_gray(self) -> T

Sets the background color to dark_gray.
Source§

fn light_red(self) -> T

Sets the foreground color to light_red.
Source§

fn on_light_red(self) -> T

Sets the background color to light_red.
Source§

fn light_green(self) -> T

Sets the foreground color to light_green.
Source§

fn on_light_green(self) -> T

Sets the background color to light_green.
Source§

fn light_yellow(self) -> T

Sets the foreground color to light_yellow.
Source§

fn on_light_yellow(self) -> T

Sets the background color to light_yellow.
Source§

fn light_blue(self) -> T

Sets the foreground color to light_blue.
Source§

fn on_light_blue(self) -> T

Sets the background color to light_blue.
Source§

fn light_magenta(self) -> T

Sets the foreground color to light_magenta.
Source§

fn on_light_magenta(self) -> T

Sets the background color to light_magenta.
Source§

fn light_cyan(self) -> T

Sets the foreground color to light_cyan.
Source§

fn on_light_cyan(self) -> T

Sets the background color to light_cyan.
Source§

fn white(self) -> T

Sets the foreground color to white.
Source§

fn on_white(self) -> T

Sets the background color to white.
Source§

fn bold(self) -> T

Adds the BOLD modifier.
Source§

fn not_bold(self) -> T

Removes the BOLD modifier.
Source§

fn dim(self) -> T

Adds the DIM modifier.
Source§

fn not_dim(self) -> T

Removes the DIM modifier.
Source§

fn italic(self) -> T

Adds the ITALIC modifier.
Source§

fn not_italic(self) -> T

Removes the ITALIC modifier.
Source§

fn underlined(self) -> T

Adds the UNDERLINED modifier.
Source§

fn not_underlined(self) -> T

Removes the UNDERLINED modifier.
Adds the SLOW_BLINK modifier.
Removes the SLOW_BLINK modifier.
Adds the RAPID_BLINK modifier.
Removes the RAPID_BLINK modifier.
Source§

fn reversed(self) -> T

Adds the REVERSED modifier.
Source§

fn not_reversed(self) -> T

Removes the REVERSED modifier.
Source§

fn hidden(self) -> T

Adds the HIDDEN modifier.
Source§

fn not_hidden(self) -> T

Removes the HIDDEN modifier.
Source§

fn crossed_out(self) -> T

Adds the CROSSED_OUT modifier.
Source§

fn not_crossed_out(self) -> T

Removes the CROSSED_OUT modifier.
Source§

impl<T> ToCompactString for T
where T: Display,

Source§

impl<T> ToLine for T
where T: Display,

Source§

fn to_line(&self) -> Line<'_>

Converts the value to a Line.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToSpan for T
where T: Display,

Source§

fn to_span(&self) -> Span<'_>

Converts the value to a Span.
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T> ToText for T
where T: Display,

Source§

fn to_text(&self) -> Text<'_>

Converts the value to a Text.
Source§

impl<T, C> TryComponentsInto<C> for T
where C: TryFromComponents<T>,

Source§

type Error = <C as TryFromComponents<T>>::Error

The error for when try_into_colors fails to cast.
Source§

fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>

Try to cast this collection of color components into a collection of colors. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T, U> TryIntoColor<U> for T
where U: TryFromColor<T>,

Source§

fn try_into_color(self) -> Result<U, OutOfBounds<U>>

Convert into T, returning ok if the color is inside of its defined range, otherwise an OutOfBounds error is returned which contains the unclamped color. Read more
Source§

impl<C, U> UintsFrom<C> for U
where C: IntoUints<U>,

Source§

fn uints_from(colors: C) -> U

Cast a collection of colors into a collection of unsigned integers.
Source§

impl<C, U> UintsInto<C> for U
where C: FromUints<U>,

Source§

fn uints_into(self) -> C

Cast this collection of unsigned integers into a collection of colors.