1use crate::console::{Console, ConsoleOptions};
7use crate::protocol::Renderable;
8use crate::segment::Segment;
9
10pub struct Constrain {
12 child: Box<dyn Renderable>,
13 width: Option<usize>,
14}
15
16impl Constrain {
17 pub fn new(child: Box<dyn Renderable>, width: Option<usize>) -> Self {
19 Constrain { child, width }
20 }
21}
22
23impl Renderable for Constrain {
24 fn rich_render(&self, console: &Console, options: &ConsoleOptions) -> Vec<Segment> {
25 let width = match self.width {
26 Some(width) => width.min(options.max_width),
27 None => options.max_width,
28 };
29 let child_options = options.update_width(width);
30 self.child.rich_render(console, &child_options)
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37 use crate::color::ColorSystem;
38 use crate::panel::Panel;
39 use crate::r#box::SQUARE;
40 use crate::text::Text;
41
42 #[test]
43 fn constrains_panel_width() {
44 let console = Console::builder()
45 .force_terminal(true)
46 .color_system(Some(ColorSystem::Truecolor))
47 .width(20)
48 .build();
49 let panel = Panel::new(Box::new(Text::new("hi"))).box_set(SQUARE);
50 let constrained = Constrain::new(Box::new(panel), Some(10));
51 let out = console.render_export(&constrained);
52 assert_eq!(out, "┌────────┐\n│ hi │\n└────────┘\n");
53 }
54}