coded_chars/control.rs
1//! This module defines the [ControlSequence] struct which represent sequence introduced by **CSI**.
2
3use std::fmt::{Display, Formatter};
4use crate::introducers::CSI;
5
6/// A control sequence is a string of bit combinations starting with the control function CONTROL
7/// SEQUENCE INTRODUCER (CSI).
8///
9/// Followed by one or more bit combinations representing parameters, if
10/// any, and by one or more bit combinations identifying the control function.
11///
12/// To "execute" a control sequence you can print it or call the method `exec` :
13/// ```
14///
15/// use coded_chars::control::ControlSequence;
16/// let sequence = ControlSequence::new(&["1", "1"], "H");
17///
18/// print!("{}", sequence); // Prints \x1b[1;1H
19/// // or
20/// sequence.exec(); // Prints \x1b[1;1H
21/// ```
22///
23/// Almost every function from this crate return [ControlSequence]s :
24///
25/// ```
26/// // This example is equivalent to the above example :
27/// use coded_chars::cursor::set_position;
28///
29/// let sequence = set_position(1, 1); // Returns a ControlSequence
30/// sequence.exec(); // Prints \x1b[1;1H
31/// ```
32#[derive(Clone)]
33pub struct ControlSequence {
34 arguments: Vec<String>,
35 end: String,
36}
37
38impl ControlSequence {
39 pub fn new(from: &[&str], end: &str) -> Self {
40 ControlSequence { arguments: from.iter().map(|s| s.to_string()).collect::<Vec<_>>(), end: end.to_string() }
41 }
42
43 /// Prints the current sequence in `stdout` directly.
44 pub fn exec(&self) {
45 use std::io::stdout;
46 use std::io::Write;
47
48 print!("{}", self);
49 stdout().flush().unwrap()
50 }
51}
52
53impl Display for ControlSequence {
54 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
55 write!(f, "{}{}{}", CSI, self.arguments.join(";"), self.end)
56 }
57}
58
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use crate::introducers::CSI;
64
65 #[test]
66 fn test_control_sequence_new() {
67 let sequence = ControlSequence::new(&["1", "1"], "H");
68 assert_eq!(sequence.arguments, vec!["1".to_string(), "1".to_string()]);
69 assert_eq!(sequence.end, "H".to_string());
70 }
71
72 #[test]
73 fn test_control_sequence_display() {
74 let sequence = ControlSequence::new(&["1", "1"], "H");
75 let expected_output = format!("{}1;1H", CSI);
76 assert_eq!(sequence.to_string(), expected_output);
77 }
78}