1use std::fmt;
4
5use ctl_text::{Context, Line, Measurement, Renderable};
6
7use crate::lines::indent_lines;
8
9pub struct Indent<'a> {
17 columns: u16,
18 child: Box<dyn Renderable + 'a>,
19}
20
21impl<'a> Indent<'a> {
22 #[must_use]
24 pub fn new(cells: u16, child: impl Renderable + 'a) -> Self {
25 Self {
26 columns: cells,
27 child: Box::new(child),
28 }
29 }
30
31 fn inner(&self, context: &Context) -> Context {
32 context.at_width(context.width().saturating_sub(self.columns).max(1))
33 }
34}
35
36impl fmt::Debug for Indent<'_> {
37 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
38 formatter
39 .debug_struct("Indent")
40 .field("columns", &self.columns)
41 .finish_non_exhaustive()
42 }
43}
44
45impl Renderable for Indent<'_> {
46 fn measure(&self, context: &Context) -> Measurement {
47 let measured = self.child.measure(&self.inner(context));
48 Measurement::new(
49 measured.minimum().saturating_add(self.columns),
50 measured.maximum().saturating_add(self.columns),
51 )
52 }
53
54 fn render(&self, context: &Context) -> Vec<Line> {
55 indent_lines(self.child.render(&self.inner(context)), self.columns)
56 }
57}