1use rsynko_ui::{Emphasis, Gauge, ScreenSyntax};
4
5#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
11pub struct TextScreen;
12
13impl ScreenSyntax for TextScreen {
14 type Text = String;
15 type Line = String;
16 type Row = Vec<String>;
17 type Body = Vec<String>;
18 type Screen = Vec<String>;
19
20 fn text(&self, content: impl Into<String>, _emphasis: Emphasis) -> Self::Text {
21 content.into()
22 }
23
24 fn gauge(&self, gauge: Gauge) -> Self::Text {
25 gauge.text()
26 }
27
28 fn line(&self, runs: impl Iterator<Item = Self::Text>) -> Self::Line {
29 runs.collect()
30 }
31
32 fn edited_line(
33 &self,
34 prefix: impl Into<String>,
35 text: &str,
36 cursor: usize,
37 _emphasis: Emphasis,
38 ) -> Self::Line {
39 let (before, after) = text.split_at(cursor.min(text.len()));
41 format!("{}{before}|{after}", prefix.into())
42 }
43
44 fn row(&self, lines: impl Iterator<Item = Self::Line>) -> Self::Row {
45 lines.collect()
46 }
47
48 fn rows(
49 &self,
50 title: impl Into<String>,
51 _focused: Option<usize>,
52 rows: impl Iterator<Item = Self::Row>,
53 ) -> Self::Body {
54 [title.into()].into_iter().chain(rows.flatten()).collect()
55 }
56
57 fn message(
58 &self,
59 title: impl Into<String>,
60 message: impl Into<String>,
61 _emphasis: Emphasis,
62 ) -> Self::Body {
63 vec![title.into(), message.into()]
64 }
65
66 fn draft(
67 &self,
68 title: impl Into<String>,
69 placeholder: impl Into<String>,
70 text: &str,
71 cursor: usize,
72 examples: impl Iterator<Item = (String, String)>,
73 ) -> Self::Body {
74 let content = if text.is_empty() {
75 placeholder.into()
76 } else {
77 self.edited_line("", text, cursor, Emphasis::Plain)
78 };
79 [title.into(), content]
80 .into_iter()
81 .chain(examples.map(|(shape, means)| format!("{shape} {means}")))
82 .collect()
83 }
84
85 fn record(&self, title: impl Into<String>, notes: impl Iterator<Item = String>) -> Self::Body {
86 [title.into()].into_iter().chain(notes).collect()
87 }
88
89 fn verbatim(&self, text: impl Into<String>) -> Self::Body {
90 vec![text.into()]
91 }
92
93 fn screen(
94 &self,
95 header: Self::Line,
96 body: Self::Body,
97 status: impl Into<String>,
98 footer: Self::Line,
99 ) -> Self::Screen {
100 [header]
101 .into_iter()
102 .chain(body)
103 .chain([status.into(), footer])
104 .collect()
105 }
106
107 fn screen_text(&self, screen: &Self::Screen) -> impl Iterator<Item = String> {
108 screen.clone().into_iter()
109 }
110}