1#[cfg(test)]
2mod tests;
3
4use heapless::Vec;
5
6#[derive(Debug, PartialEq, Clone)]
8pub enum AnsiSequence {
9 Escape,
10 CursorPos(u32, u32),
11 CursorUp(u32),
12 CursorDown(u32),
13 CursorForward(u32),
14 CursorBackward(u32),
15 CursorSave,
16 CursorRestore,
17 EraseDisplay,
18 EraseLine,
19 SetGraphicsMode(Vec<u8, 5>),
20 SetMode(u8),
21 ResetMode(u8),
22 HideCursor,
23 ShowCursor,
24 CursorToApp,
25 SetNewLineMode,
26 SetCol132,
27 SetSmoothScroll,
28 SetReverseVideo,
29 SetOriginRelative,
30 SetAutoWrap,
31 SetAutoRepeat,
32 SetInterlacing,
33 SetLineFeedMode,
34 SetCursorKeyToCursor,
35 SetVT52,
36 SetCol80,
37 SetJumpScrolling,
38 SetNormalVideo,
39 SetOriginAbsolute,
40 ResetAutoWrap,
41 ResetAutoRepeat,
42 ResetInterlacing,
43 SetAlternateKeypad,
44 SetNumericKeypad,
45 SetUKG0,
46 SetUKG1,
47 SetUSG0,
48 SetUSG1,
49 SetG0SpecialChars,
50 SetG1SpecialChars,
51 SetG0AlternateChar,
52 SetG1AlternateChar,
53 SetG0AltAndSpecialGraph,
54 SetG1AltAndSpecialGraph,
55 SetSingleShift2,
56 SetSingleShift3,
57 SetTopAndBottom(u32, u32),
58}
59
60use core::fmt::{Display, Formatter, Result as DisplayResult};
61impl Display for AnsiSequence {
62 fn fmt(&self, formatter: &mut Formatter) -> DisplayResult {
63 write!(formatter, "\u{1b}")?;
64
65 use AnsiSequence::*;
66 match self {
67 Escape => write!(formatter, "\u{1b}"),
68 CursorPos(line, col) => write!(formatter, "[{};{}H", line, col),
69 CursorUp(amt) => write!(formatter, "[{}A", amt),
70 CursorDown(amt) => write!(formatter, "[{}B", amt),
71 CursorForward(amt) => write!(formatter, "[{}C", amt),
72 CursorBackward(amt) => write!(formatter, "[{}D", amt),
73 CursorSave => write!(formatter, "[s"),
74 CursorRestore => write!(formatter, "[u"),
75 EraseDisplay => write!(formatter, "[2J"),
76 EraseLine => write!(formatter, "[K"),
77 SetGraphicsMode(vec) => match vec.len() {
78 0 => write!(formatter, "[m"),
79 1 => write!(formatter, "[{}m", vec[0]),
80 2 => write!(formatter, "[{};{}m", vec[0], vec[1]),
81 3 => write!(formatter, "[{};{};{}m", vec[0], vec[1], vec[2]),
82 5 => write!(
83 formatter,
84 "[{};{};{};{};{}m",
85 vec[0], vec[1], vec[2], vec[3], vec[4]
86 ),
87 _ => unreachable!(),
88 },
89 SetMode(mode) => write!(formatter, "[={}h", mode),
90 ResetMode(mode) => write!(formatter, "[={}l", mode),
91 ShowCursor => write!(formatter, "[?25h"),
92 HideCursor => write!(formatter, "[?25l"),
93 CursorToApp => write!(formatter, "[?1h"),
94 SetNewLineMode => write!(formatter, "[20h"),
95 SetCol132 => write!(formatter, "[?3h"),
96 SetSmoothScroll => write!(formatter, "[?4h"),
97 SetReverseVideo => write!(formatter, "[?5h"),
98 SetOriginRelative => write!(formatter, "[?6h"),
99 SetAutoWrap => write!(formatter, "[?7h"),
100 SetAutoRepeat => write!(formatter, "[?8h"),
101 SetInterlacing => write!(formatter, "[?9h"),
102 SetLineFeedMode => write!(formatter, "[20l"),
103 SetCursorKeyToCursor => write!(formatter, "[?1l"),
104 SetVT52 => write!(formatter, "[?2l"),
105 SetCol80 => write!(formatter, "[?3l"),
106 SetJumpScrolling => write!(formatter, "[?4l"),
107 SetNormalVideo => write!(formatter, "[?5l"),
108 SetOriginAbsolute => write!(formatter, "[?6l"),
109 ResetAutoWrap => write!(formatter, "[?7l"),
110 ResetAutoRepeat => write!(formatter, "[?8l"),
111 ResetInterlacing => write!(formatter, "[?9l"),
112 SetAlternateKeypad => write!(formatter, "="),
113 SetNumericKeypad => write!(formatter, ">"),
114 SetUKG0 => write!(formatter, "(A"),
115 SetUKG1 => write!(formatter, ")A"),
116 SetUSG0 => write!(formatter, "(B"),
117 SetUSG1 => write!(formatter, ")B"),
118 SetG0SpecialChars => write!(formatter, "(0"),
119 SetG1SpecialChars => write!(formatter, ")0"),
120 SetG0AlternateChar => write!(formatter, "(1"),
121 SetG1AlternateChar => write!(formatter, ")1"),
122 SetG0AltAndSpecialGraph => write!(formatter, "(2"),
123 SetG1AltAndSpecialGraph => write!(formatter, ")2"),
124 SetSingleShift2 => write!(formatter, "N"),
125 SetSingleShift3 => write!(formatter, "O"),
126 SetTopAndBottom(x, y) => write!(formatter, "{};{}r", x, y),
127 }
128 }
129}
130
131#[derive(Debug, Clone, PartialEq)]
135pub enum Output<'a> {
136 TextBlock(&'a str),
137 Escape(AnsiSequence),
138}
139
140impl<'a> Display for Output<'a> {
141 fn fmt(&self, formatter: &mut Formatter) -> DisplayResult {
142 use Output::*;
143 match self {
144 TextBlock(txt) => write!(formatter, "{}", txt),
145 Escape(seq) => write!(formatter, "{}", seq),
146 }
147 }
148}