ansi_escape_codes/
lib.rs

1// Source: https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_(Control_Sequence_Introducer)_sequences
2
3use std::fmt;
4
5pub enum ASCIIControlCode {
6    NullCode,
7    StartOfHeadingCode,
8    StartOfTextCode,
9    EndofTextCode,
10    EndOfTransmissionCode,
11    EnquiryCode,
12    AcknowledgeCode,
13    BellCode,
14    BackspaceCode,
15    HorizontalTabCode,
16    LineFeedCode,
17    VerticalTabCode,
18    FormFeedCode,
19    CarriageReturnCode,
20    ShiftOutCode,
21    ShiftInCode,
22    DataLinkEscapeCode,
23    DeviceControlOneCode,
24    DeviceControlTwoCode,
25    DeviceControlThreeCode,
26    DeviceControlFourCode,
27    NegativeAcknowledgeCode,
28    SynchronousIdleCode,
29    EndOfTransmissionBlockCode,
30    CancelCode,
31    EndOfMediumCode,
32    SubsituteCode,
33    EscapeCode,
34    FileSeperatorCode,
35    GroupSeperatorCode,
36    RecordSeperatorCode,
37    UnitSeperatorCode,
38    SpaceCode,
39    DeleteCode,
40}
41
42impl ASCIIControlCode {
43    pub fn to_string(self) -> String {
44        match self {
45            ASCIIControlCode::EscapeCode => String::from("\x1b"),
46            ASCIIControlCode::LineFeedCode=> String::from("\x0A"),
47            ASCIIControlCode::CarriageReturnCode => String::from("\x0D"),
48            _ => panic!(), // TODO: Implement the rest
49        }
50    }
51}
52
53pub enum ControlSequenceInducerParameter {
54    CursorUpParameter(u32),
55    CursorDownParameter(u32),
56    CursorForwardParameter(u32),
57    CursorBackParameter(u32),
58    CursorNextLineParameter(u32),
59    CursorPreviousLineParameter(u32),
60    CursorHorizontalAbsoluteParameter(u32),
61    CursorPositionParameter(u32, u32),
62    EraseScreenAfterCursorParameter,
63    EraseScreenBeforeCursorParameter,
64    EraseScreenParameter,
65    EraseScreenAndScrollbackParameter,
66    EraseLineAfterCursorParameter,
67    EraseLineBeforeCursorParameter,
68    EraseLineParameter,
69    ScrollUpParameter(u32),
70    ScrollDownParameter(u32),
71    HorizontalVerticalPositionParameter(u32, u32),
72    SelectGraphicRenditionSequenceParameter(Vec<SelectGraphicRenditionParameter>),
73    AUXPortOnParameter,
74    AUXPortOffParameter,
75    DeviceStatusReportParameter,
76    SaveCursorPositionParameter,
77    RestoreCursorPositionParameter,
78}
79
80impl ControlSequenceInducerParameter {
81    pub fn to_string(self) -> String {
82        match self {
83            ControlSequenceInducerParameter::CursorUpParameter(move_count) => {
84                return format!("{}A", move_count.to_string());
85            }
86            ControlSequenceInducerParameter::CursorDownParameter(move_count) => {
87                return format!("{}B", move_count.to_string());
88            }
89            ControlSequenceInducerParameter::CursorForwardParameter(move_count) => {
90                return format!("{}C", move_count.to_string());
91            }
92            ControlSequenceInducerParameter::CursorBackParameter(move_count) => {
93                return format!("{}D", move_count.to_string());
94            }
95            ControlSequenceInducerParameter::CursorNextLineParameter(move_count) => {
96                return format!("{}E", move_count.to_string());
97            }
98            ControlSequenceInducerParameter::CursorPreviousLineParameter(move_count) => {
99                return format!("{}F", move_count.to_string());
100            }
101            ControlSequenceInducerParameter::CursorHorizontalAbsoluteParameter(move_count) => {
102                return format!("{}F", move_count.to_string());
103            }
104            ControlSequenceInducerParameter::CursorPositionParameter(
105                row_position,
106                column_position,
107            ) => {
108                return format!(
109                    "{};{}H",
110                    row_position.to_string(),
111                    column_position.to_string()
112                );
113            }
114            ControlSequenceInducerParameter::EraseScreenAfterCursorParameter => String::from("0J"),
115            ControlSequenceInducerParameter::EraseScreenBeforeCursorParameter => String::from("1J"),
116            ControlSequenceInducerParameter::EraseScreenParameter => String::from("2J"),
117            ControlSequenceInducerParameter::EraseScreenAndScrollbackParameter => {
118                String::from("3J")
119            }
120            ControlSequenceInducerParameter::EraseLineAfterCursorParameter => String::from("0K"),
121            ControlSequenceInducerParameter::EraseLineBeforeCursorParameter => String::from("1K"),
122            ControlSequenceInducerParameter::EraseLineParameter => String::from("2K"),
123            ControlSequenceInducerParameter::ScrollUpParameter(move_count) => {
124                return format!("{}S", move_count.to_string());
125            }
126            ControlSequenceInducerParameter::ScrollDownParameter(move_count) => {
127                return format!("{}T", move_count.to_string());
128            }
129            ControlSequenceInducerParameter::HorizontalVerticalPositionParameter(
130                row_position,
131                column_position,
132            ) => {
133                return format!(
134                    "{};{}f",
135                    row_position.to_string(),
136                    column_position.to_string()
137                );
138            }
139            ControlSequenceInducerParameter::SelectGraphicRenditionSequenceParameter(params) => {
140                let s: String = params
141                    .into_iter()
142                    .map(|param| format!("{};", param.to_string()))
143                    .collect();
144                return format!("{}m", s);
145            }
146            ControlSequenceInducerParameter::AUXPortOnParameter => String::from("5i"),
147            ControlSequenceInducerParameter::AUXPortOffParameter => String::from("4i"),
148            ControlSequenceInducerParameter::DeviceStatusReportParameter => String::from("6n"), // TODO: This is probably wrong
149            ControlSequenceInducerParameter::SaveCursorPositionParameter => String::from("s"),
150            ControlSequenceInducerParameter::RestoreCursorPositionParameter => String::from("u"),
151        }
152    }
153}
154
155pub enum SelectGraphicRenditionParameter {
156    ResetNormalParameter,
157    BoldParameter,
158    IncreasedSensitivityParameter,
159    FaintParameter,
160    DecreasedSensitivityParameter,
161    ItalicParameter,
162    UnderlineParameter,
163    SlowBlinkParameter,
164    RapidBlinkParameter,
165    ReverseVideoParameter,
166    ConcealParameter,
167    CrossedOutParameter,
168    PrimaryFontParameter,
169    DefaultFontParameter,
170    AlternativeFontParameter(u32), // TODO: x should only be 11-19
171    FrakturParameter,
172    BoldOffParameter,
173    DoubleUnderlineParameter,
174    NormalColorParameter,
175    NormalIntensityParameter,
176    NotItalicParameter,
177    NotFrakturParameter,
178    UnderlineOffParameter,
179    BlinkOffParameter,
180    InverseOffParameter,
181    RevealParameter,
182    NotCrossedOutParameter,
183    SetForegroundColorParameter(ForegroundColor),
184    DefaultForegroundColorParameter,
185    SetBackgroundColorParameter(BackgroundColor),
186    DefaultBackgroundColorParameter,
187    FramedParameter,
188    EncircledParameter,
189    OverlinedParameter,
190    NotFramedParameter,
191    NotEncircledParameter,
192    NotOverlinedParameter,
193    IdeogramUnderlineParameter,
194    RightSideLineParameter,
195    // IdeogramDoubleUnderlineParameter,
196    // DoubleLIneOnRightSideParameter,
197    // IdeogramStressMarkingParameter,
198    // IdeogramAttributesOffParameter,
199    SetBrightForegroundColorParameter(BrightForegroundColor),
200    SetBrightBackgroundColorParameter(BrightBackgroundColor),
201}
202
203impl SelectGraphicRenditionParameter {
204    pub fn to_string(self) -> String {
205        match self {
206            SelectGraphicRenditionParameter::ResetNormalParameter => String::from("0"),
207            SelectGraphicRenditionParameter::BoldParameter => String::from("1"),
208            SelectGraphicRenditionParameter::IncreasedSensitivityParameter => String::from("1"),
209            SelectGraphicRenditionParameter::FaintParameter => String::from("2"),
210            SelectGraphicRenditionParameter::DecreasedSensitivityParameter => String::from("2"),
211            SelectGraphicRenditionParameter::ItalicParameter => String::from("3"),
212            SelectGraphicRenditionParameter::UnderlineParameter => String::from("4"),
213            SelectGraphicRenditionParameter::SlowBlinkParameter => String::from("5"),
214            SelectGraphicRenditionParameter::RapidBlinkParameter => String::from("6"),
215            SelectGraphicRenditionParameter::ReverseVideoParameter => String::from("7"),
216            SelectGraphicRenditionParameter::ConcealParameter => String::from("8"),
217            SelectGraphicRenditionParameter::CrossedOutParameter => String::from("9"),
218            SelectGraphicRenditionParameter::PrimaryFontParameter => String::from("10"),
219            SelectGraphicRenditionParameter::DefaultFontParameter => String::from("10"),
220            SelectGraphicRenditionParameter::AlternativeFontParameter(x) => x.to_string(),
221            SelectGraphicRenditionParameter::FrakturParameter => String::from("20"),
222            SelectGraphicRenditionParameter::BoldOffParameter => String::from("21"),
223            SelectGraphicRenditionParameter::DoubleUnderlineParameter => String::from("21"),
224            SelectGraphicRenditionParameter::NormalColorParameter => String::from("22"),
225            SelectGraphicRenditionParameter::NormalIntensityParameter => String::from("22"),
226            SelectGraphicRenditionParameter::NotItalicParameter => String::from("23"),
227            SelectGraphicRenditionParameter::NotFrakturParameter => String::from("23"),
228            SelectGraphicRenditionParameter::UnderlineOffParameter => String::from("24"),
229            SelectGraphicRenditionParameter::BlinkOffParameter => String::from("25"),
230            SelectGraphicRenditionParameter::InverseOffParameter => String::from("27"),
231            SelectGraphicRenditionParameter::RevealParameter => String::from("28"),
232            SelectGraphicRenditionParameter::NotCrossedOutParameter => String::from("29"),
233            SelectGraphicRenditionParameter::SetForegroundColorParameter(foreground_color) => {
234                return format!("38;{}", foreground_color.to_string())
235            }
236            SelectGraphicRenditionParameter::DefaultForegroundColorParameter => String::from("39"),
237            SelectGraphicRenditionParameter::SetBackgroundColorParameter(background_color) => {
238                return format!("48;{}", background_color.to_string())
239            }
240            SelectGraphicRenditionParameter::DefaultBackgroundColorParameter => String::from("49"),
241            SelectGraphicRenditionParameter::FramedParameter => String::from("51"),
242            SelectGraphicRenditionParameter::EncircledParameter => String::from("52"),
243            SelectGraphicRenditionParameter::OverlinedParameter => String::from("53"),
244            SelectGraphicRenditionParameter::NotFramedParameter => String::from("54"),
245            SelectGraphicRenditionParameter::NotEncircledParameter => String::from("54"),
246            SelectGraphicRenditionParameter::NotOverlinedParameter => String::from("53"),
247            SelectGraphicRenditionParameter::IdeogramUnderlineParameter => String::from("60"),
248            SelectGraphicRenditionParameter::SetBrightForegroundColorParameter(
249                foreground_color,
250            ) => foreground_color.to_string(),
251            SelectGraphicRenditionParameter::SetBrightBackgroundColorParameter(
252                background_color,
253            ) => background_color.to_string(),
254            _ => panic!(), //TODO: Implement the rest
255        }
256    }
257}
258
259pub enum ForegroundColor {
260    BlackForeground,
261    RedForeground,
262    GreenForeground,
263    YellowForeground,
264    BlueForeground,
265    MagentaForeground,
266    CyanForeground,
267    WhiteForeground,
268    ForegroundColor(Color),
269}
270
271impl ForegroundColor {
272    pub fn to_string(self) -> String {
273        match self {
274            ForegroundColor::BlackForeground => String::from("30"),
275            ForegroundColor::RedForeground => String::from("31"),
276            ForegroundColor::GreenForeground => String::from("32"),
277            ForegroundColor::YellowForeground => String::from("33"),
278            ForegroundColor::BlueForeground => String::from("34"),
279            ForegroundColor::MagentaForeground => String::from("35"),
280            ForegroundColor::CyanForeground => String::from("36"),
281            ForegroundColor::WhiteForeground => String::from("37"),
282            ForegroundColor::ForegroundColor(color) => color.to_string(),
283        }
284    }
285}
286
287pub enum BrightForegroundColor {
288    BrightBlackForeground,
289    BrightRedForeground,
290    BrightGreenForeground,
291    BrightYellowForeground,
292    BrightBlueForeground,
293    BrightMagentaForeground,
294    BrightCyanForeground,
295    BrightWhiteForeground,
296}
297impl BrightForegroundColor {
298    pub fn to_string(self) -> String {
299        match self {
300            BrightForegroundColor::BrightBlackForeground => String::from("1;30"),
301            BrightForegroundColor::BrightRedForeground => String::from("1;31"),
302            BrightForegroundColor::BrightGreenForeground => String::from("1;32"),
303            BrightForegroundColor::BrightYellowForeground => String::from("1;33"),
304            BrightForegroundColor::BrightBlueForeground => String::from("1;34"),
305            BrightForegroundColor::BrightMagentaForeground => String::from("1;35"),
306            BrightForegroundColor::BrightCyanForeground => String::from("1;36"),
307            BrightForegroundColor::BrightWhiteForeground => String::from("1;37"),
308        }
309    }
310}
311
312pub enum BackgroundColor {
313    BlackBackground,
314    RedBackground,
315    GreenBackground,
316    YellowBackground,
317    BlueBackground,
318    MagentaBackground,
319    CyanBackground,
320    WhiteBackground,
321    BackgroundColor(Color),
322}
323
324impl BackgroundColor {
325    pub fn to_string(self) -> String {
326        match self {
327            BackgroundColor::BlackBackground => String::from("40"),
328            BackgroundColor::RedBackground => String::from("41"),
329            BackgroundColor::GreenBackground => String::from("42"),
330            BackgroundColor::YellowBackground => String::from("43"),
331            BackgroundColor::BlueBackground => String::from("44"),
332            BackgroundColor::MagentaBackground => String::from("45"),
333            BackgroundColor::CyanBackground => String::from("46"),
334            BackgroundColor::WhiteBackground => String::from("47"),
335            BackgroundColor::BackgroundColor(color) => color.to_string(),
336        }
337    }
338}
339
340pub enum BrightBackgroundColor {
341    BrightBlackBackground,
342    BrightRedBackground,
343    BrightGreenBackground,
344    BrightYellowBackground,
345    BrightBlueBackground,
346    BrightMagentaBackground,
347    BrightCyanBackground,
348    BrightWhiteBackground,
349}
350
351impl BrightBackgroundColor {
352    pub fn to_string(self) -> String {
353        match self {
354            BrightBackgroundColor::BrightBlackBackground => String::from("100"),
355            BrightBackgroundColor::BrightRedBackground => String::from("101"),
356            BrightBackgroundColor::BrightGreenBackground => String::from("102"),
357            BrightBackgroundColor::BrightYellowBackground => String::from("103"),
358            BrightBackgroundColor::BrightBlueBackground => String::from("104"),
359            BrightBackgroundColor::BrightMagentaBackground => String::from("105"),
360            BrightBackgroundColor::BrightCyanBackground => String::from("106"),
361            BrightBackgroundColor::BrightWhiteBackground => String::from("107"),
362        }
363    }
364}
365
366pub type ColorCode = u32;
367pub type RedColorCode = ColorCode;
368pub type GreenColorCode = ColorCode;
369pub type BlueColorCode = ColorCode;
370
371pub enum Color {
372    Color256(ColorCode), // TODO: Validate only integers 1-256
373    RGB(RedColorCode, GreenColorCode, BlueColorCode), // TODO: Validate only integers 1-256
374}
375
376impl Color {
377    pub fn to_string(self) -> String {
378        match self {
379            Color::Color256(color_code) => format!("5;{}", color_code.to_string()),
380            Color::RGB(red_color_code, green_color_code, blue_color_code) => format!(
381                "2;{};{};{}",
382                red_color_code.to_string(),
383                green_color_code.to_string(),
384                blue_color_code.to_string()
385            ),
386        }
387    }
388}
389
390pub enum EscapeSequence {
391    CursorUpSequence(u32),
392    CursorDownSequence(u32),
393    CursorForwardSequence(u32),
394    CursorBackSequence(u32),
395    CursorNextLineSequence(u32),
396    CursorPreviousLineSequence(u32),
397    CursorHorizontalAbsoluteSequence(u32),
398    CursorPositionSequence(u32, u32),
399    EraseScreenAfterCursorSequence,
400    EraseScreenBeforeCursorSequence,
401    EraseScreenSequence,
402    EraseScreenAndScrollbackSequence,
403    EraseLineAfterCursorSequence,
404    EraseLineBeforeCursorSequence,
405    EraseLineSequence,
406    ScrollUpSequence(u32),
407    ScrollDownSequence(u32),
408    HorizontalVerticalPositionSequence(u32, u32),
409    SelectGraphicRenditionSequence(Vec<SelectGraphicRenditionParameter>),
410    AUXPortOnSequence,
411    AUXPortOffSequence,
412    DeviceStatusReportSequence,
413    SaveCursorPositionSequence,
414    RestoreCursorPositionSequence,
415    ResetColorsSequence,
416    ResetAttributesSequence,
417}
418
419impl EscapeSequence {
420    pub fn to_string(self) -> String {
421        match self {
422            EscapeSequence::CursorUpSequence(move_count) => {
423                return format!(
424                    "{}{}",
425                    ControlSequencePart::ControlSequenceInducer.to_string(),
426                    ControlSequencePart::ControlSequenceInducerParameter(
427                        ControlSequenceInducerParameter::CursorUpParameter(move_count)
428                    )
429                    .to_string()
430                );
431            }
432            EscapeSequence::CursorDownSequence(move_count) => {
433                return format!(
434                    "{}{}",
435                    ControlSequencePart::ControlSequenceInducer.to_string(),
436                    ControlSequencePart::ControlSequenceInducerParameter(
437                        ControlSequenceInducerParameter::CursorDownParameter(move_count)
438                    )
439                    .to_string()
440                );
441            }
442            EscapeSequence::CursorForwardSequence(move_count) => {
443                return format!(
444                    "{}{}",
445                    ControlSequencePart::ControlSequenceInducer.to_string(),
446                    ControlSequencePart::ControlSequenceInducerParameter(
447                        ControlSequenceInducerParameter::CursorForwardParameter(move_count)
448                    )
449                    .to_string()
450                );
451            }
452            EscapeSequence::CursorBackSequence(move_count) => {
453                return format!(
454                    "{}{}",
455                    ControlSequencePart::ControlSequenceInducer.to_string(),
456                    ControlSequencePart::ControlSequenceInducerParameter(
457                        ControlSequenceInducerParameter::CursorBackParameter(move_count)
458                    )
459                    .to_string()
460                );
461            }
462            EscapeSequence::CursorNextLineSequence(move_count) => {
463                return format!(
464                    "{}{}",
465                    ControlSequencePart::ControlSequenceInducer.to_string(),
466                    ControlSequencePart::ControlSequenceInducerParameter(
467                        ControlSequenceInducerParameter::CursorNextLineParameter(move_count)
468                    )
469                    .to_string()
470                );
471            }
472            EscapeSequence::CursorPreviousLineSequence(move_count) => {
473                return format!(
474                    "{}{}",
475                    ControlSequencePart::ControlSequenceInducer.to_string(),
476                    ControlSequencePart::ControlSequenceInducerParameter(
477                        ControlSequenceInducerParameter::CursorPreviousLineParameter(move_count)
478                    )
479                    .to_string()
480                );
481            }
482            EscapeSequence::CursorHorizontalAbsoluteSequence(move_count) => {
483                return format!(
484                    "{}{}",
485                    ControlSequencePart::ControlSequenceInducer.to_string(),
486                    ControlSequencePart::ControlSequenceInducerParameter(
487                        ControlSequenceInducerParameter::CursorHorizontalAbsoluteParameter(
488                            move_count
489                        )
490                    )
491                    .to_string()
492                );
493            }
494            EscapeSequence::CursorPositionSequence(row_position, column_position) => {
495                return format!(
496                    "{}{}",
497                    ControlSequencePart::ControlSequenceInducer.to_string(),
498                    ControlSequencePart::ControlSequenceInducerParameter(
499                        ControlSequenceInducerParameter::CursorPositionParameter(
500                            row_position,
501                            column_position
502                        )
503                    )
504                    .to_string()
505                );
506            }
507            EscapeSequence::EraseScreenAfterCursorSequence => {
508                return format!(
509                    "{}{}",
510                    ControlSequencePart::ControlSequenceInducer.to_string(),
511                    ControlSequencePart::ControlSequenceInducerParameter(
512                        ControlSequenceInducerParameter::EraseScreenAfterCursorParameter
513                    )
514                    .to_string()
515                );
516            }
517            EscapeSequence::EraseScreenBeforeCursorSequence => {
518                return format!(
519                    "{}{}",
520                    ControlSequencePart::ControlSequenceInducer.to_string(),
521                    ControlSequencePart::ControlSequenceInducerParameter(
522                        ControlSequenceInducerParameter::EraseScreenBeforeCursorParameter
523                    )
524                    .to_string()
525                );
526            }
527            EscapeSequence::EraseScreenSequence => {
528                return format!(
529                    "{}{}",
530                    ControlSequencePart::ControlSequenceInducer.to_string(),
531                    ControlSequencePart::ControlSequenceInducerParameter(
532                        ControlSequenceInducerParameter::EraseScreenParameter
533                    )
534                    .to_string()
535                );
536            }
537            EscapeSequence::EraseScreenAndScrollbackSequence => {
538                return format!(
539                    "{}{}",
540                    ControlSequencePart::ControlSequenceInducer.to_string(),
541                    ControlSequencePart::ControlSequenceInducerParameter(
542                        ControlSequenceInducerParameter::EraseScreenAndScrollbackParameter
543                    )
544                    .to_string()
545                );
546            }
547            EscapeSequence::EraseLineAfterCursorSequence => {
548                return format!(
549                    "{}{}",
550                    ControlSequencePart::ControlSequenceInducer.to_string(),
551                    ControlSequencePart::ControlSequenceInducerParameter(
552                        ControlSequenceInducerParameter::EraseLineAfterCursorParameter
553                    )
554                    .to_string()
555                );
556            }
557            EscapeSequence::EraseLineBeforeCursorSequence => {
558                return format!(
559                    "{}{}",
560                    ControlSequencePart::ControlSequenceInducer.to_string(),
561                    ControlSequencePart::ControlSequenceInducerParameter(
562                        ControlSequenceInducerParameter::EraseLineBeforeCursorParameter
563                    )
564                    .to_string()
565                );
566            }
567            EscapeSequence::EraseLineSequence => {
568                return format!(
569                    "{}{}",
570                    ControlSequencePart::ControlSequenceInducer.to_string(),
571                    ControlSequencePart::ControlSequenceInducerParameter(
572                        ControlSequenceInducerParameter::EraseLineParameter
573                    )
574                    .to_string()
575                );
576            }
577            EscapeSequence::ScrollUpSequence(move_count) => {
578                return format!(
579                    "{}{}",
580                    ControlSequencePart::ControlSequenceInducer.to_string(),
581                    ControlSequencePart::ControlSequenceInducerParameter(
582                        ControlSequenceInducerParameter::ScrollUpParameter(move_count)
583                    )
584                    .to_string()
585                );
586            }
587            EscapeSequence::ScrollDownSequence(move_count) => {
588                return format!(
589                    "{}{}",
590                    ControlSequencePart::ControlSequenceInducer.to_string(),
591                    ControlSequencePart::ControlSequenceInducerParameter(
592                        ControlSequenceInducerParameter::ScrollDownParameter(move_count)
593                    )
594                    .to_string()
595                );
596            }
597            EscapeSequence::HorizontalVerticalPositionSequence(row_position, column_position) => {
598                return format!(
599                    "{}{}",
600                    ControlSequencePart::ControlSequenceInducer.to_string(),
601                    ControlSequencePart::ControlSequenceInducerParameter(
602                        ControlSequenceInducerParameter::HorizontalVerticalPositionParameter(
603                            row_position,
604                            column_position
605                        )
606                    )
607                    .to_string()
608                );
609            }
610            EscapeSequence::SelectGraphicRenditionSequence(params) => {
611                return format!(
612                    "{}{}",
613                    ControlSequencePart::ControlSequenceInducer.to_string(),
614                    ControlSequencePart::ControlSequenceInducerParameter(
615                        ControlSequenceInducerParameter::SelectGraphicRenditionSequenceParameter(
616                            params
617                        )
618                    )
619                    .to_string()
620                );
621            }
622            EscapeSequence::AUXPortOnSequence => {
623                return format!(
624                    "{}{}",
625                    ControlSequencePart::ControlSequenceInducer.to_string(),
626                    ControlSequencePart::ControlSequenceInducerParameter(
627                        ControlSequenceInducerParameter::AUXPortOnParameter
628                    )
629                    .to_string()
630                );
631            }
632            EscapeSequence::AUXPortOffSequence => {
633                return format!(
634                    "{}{}",
635                    ControlSequencePart::ControlSequenceInducer.to_string(),
636                    ControlSequencePart::ControlSequenceInducerParameter(
637                        ControlSequenceInducerParameter::AUXPortOffParameter
638                    )
639                    .to_string()
640                );
641            }
642            EscapeSequence::DeviceStatusReportSequence => {
643                return format!(
644                    "{}{}",
645                    ControlSequencePart::ControlSequenceInducer.to_string(),
646                    ControlSequencePart::ControlSequenceInducerParameter(
647                        ControlSequenceInducerParameter::DeviceStatusReportParameter
648                    )
649                    .to_string()
650                );
651            }
652            EscapeSequence::SaveCursorPositionSequence => {
653                return format!(
654                    "{}{}",
655                    ControlSequencePart::ControlSequenceInducer.to_string(),
656                    ControlSequencePart::ControlSequenceInducerParameter(
657                        ControlSequenceInducerParameter::SaveCursorPositionParameter
658                    )
659                    .to_string()
660                );
661            }
662            EscapeSequence::RestoreCursorPositionSequence => {
663                return format!(
664                    "{}{}",
665                    ControlSequencePart::ControlSequenceInducer.to_string(),
666                    ControlSequencePart::ControlSequenceInducerParameter(
667                        ControlSequenceInducerParameter::RestoreCursorPositionParameter
668                    )
669                    .to_string()
670                );
671            }
672            EscapeSequence::ResetColorsSequence => {
673                return format!(
674                    "{}0m",
675                    ControlSequencePart::ControlSequenceInducer.to_string(),
676                );
677            }
678            EscapeSequence::ResetAttributesSequence => {
679                return format!(
680                    "{}39;49m",
681                    ControlSequencePart::ControlSequenceInducer.to_string(),
682                );
683            }
684        }
685    }
686}
687
688// defined as an escape character followed immediately by a bracket: ESC[.
689pub enum ControlSequencePart {
690    ControlSequenceInducer,
691    ControlSequenceInducerParameter(ControlSequenceInducerParameter),
692}
693
694impl ControlSequencePart {
695    pub fn to_string(self) -> String {
696        match self {
697            ControlSequencePart::ControlSequenceInducer => {
698                format!("{}[", ASCIIControlCode::EscapeCode.to_string())
699            }
700            ControlSequencePart::ControlSequenceInducerParameter(param) => {
701                format!("{}", param.to_string())
702            }
703            _ => String::from("ERROR"),
704        }
705    }
706}