use alloc::borrow::ToOwned as _;
use alloc::string::String;
use retroglyph_core::color::Style;
use retroglyph_core::grid::{Pos, Rect};
use retroglyph_core::text::{split_at_width, truncate_measured};
use crate::{Align, Surface};
#[must_use]
pub fn truncate(s: &str, max_cols: impl Into<usize>) -> &str {
let max_cols = max_cols.into();
#[allow(clippy::cast_possible_truncation)] let max_cols = max_cols.min(usize::from(u16::MAX)) as u16;
split_at_width(s, max_cols).0
}
#[must_use]
pub fn truncate_owned(s: &str, max_cols: impl Into<usize>) -> String {
truncate(s, max_cols).to_owned()
}
#[must_use]
pub fn draw_clipped(
surface: &mut Surface<'_>,
at: impl Into<Pos>,
width: u16,
text: &str,
align: Align,
style: Style,
) -> u16 {
let at = at.into();
let (clipped, clipped_width) = truncate_measured(text, width);
surface.print_aligned(Rect::new(at.x, at.y, width, 1), clipped, align, style);
clipped_width
}
#[cfg(test)]
mod tests {
use retroglyph_core::grid::{Grid, Rect};
use super::*;
#[test]
fn truncate_stops_at_the_column_budget() {
assert_eq!(truncate("hello world", 5usize), "hello");
assert_eq!(truncate("hi", 10usize), "hi");
assert_eq!(truncate("hi", 0usize), "");
}
#[test]
fn truncate_counts_wide_characters_as_two_columns() {
assert_eq!(truncate("aあb", 2usize), "a");
assert_eq!(truncate("aあb", 3usize), "aあ");
assert_eq!(truncate("ああ", 3usize), "あ");
}
fn row(grid: &Grid, width: u16) -> String {
(0..width).map(|x| grid[Pos::new(x, 0)].glyph()).collect()
}
#[test]
fn draw_clipped_left_aligns_and_returns_the_printed_width() {
let mut grid = Grid::new(10, 1);
let printed = draw_clipped(
&mut Surface::new(&mut grid, Rect::new(0, 0, 10, 1), 0),
(0, 0),
10,
"hi",
Align::Left,
Style::new(),
);
assert_eq!(printed, 2);
assert_eq!(row(&grid, 10), "hi ");
}
#[test]
fn draw_clipped_centers_within_width() {
let mut grid = Grid::new(10, 1);
let _ = draw_clipped(
&mut Surface::new(&mut grid, Rect::new(0, 0, 10, 1), 0),
(0, 0),
10,
"hi",
Align::Center,
Style::new(),
);
assert_eq!(row(&grid, 10), " hi ");
}
#[test]
fn draw_clipped_truncates_wide_characters_before_measuring() {
let mut grid = Grid::new(3, 1);
let printed = draw_clipped(
&mut Surface::new(&mut grid, Rect::new(0, 0, 3, 1), 0),
(0, 0),
3,
"ああ",
Align::Center,
Style::new(),
);
assert_eq!(printed, 2);
assert_eq!(row(&grid, 3), "あ ");
}
}