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}