1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use std::str;
use std::time::Duration;

use serialport::{self, SerialPort};
pub struct Neobridge {
    port: Box<dyn SerialPort>, 
    number_of_leds: u32
}

#[derive(Debug)]
pub struct RGB(pub u8, pub u8, pub u8);

impl RGB {
    pub fn to_string(&self) -> String {
        return format!("({0}, {1}, {2})", self.0, self.1, self.2);
    }
}

impl Neobridge {

    pub fn new(port: &str, number_of_leds: u32) -> Neobridge {
        Neobridge {
            port: serialport::new(port, 115_200)
                .timeout(Duration::from_millis(10))
                .open().expect("Failed to open port"),
            number_of_leds: number_of_leds
        }
    }

    fn replace_with_color(&mut self, msg: &str, color: RGB) -> String {
        let mut replace = str::replace(msg, "{0}", color.0.to_string().as_str());
        replace = str::replace(replace.as_str(), "{1}", color.1.to_string().as_str());
        replace = str::replace(replace.as_str(), "{2}", color.2.to_string().as_str());
        return replace;
    }

    fn send_message(&mut self, message: &str) {
        self.port.write(message.as_bytes()).expect("could not write to serial port");
        self.port.write("\r\n".as_bytes()).expect("could not write to serial port");
        self.port.flush().expect("could not flush to serial port");
    }
    
    pub fn show(&mut self) {
        self.send_message(r#"{"command": -3}"#);
    }

    pub fn set_all(&mut self, color: RGB) {
        let msg = self.replace_with_color(r#"{"command": 0, "r": {0}, "g": {1}, "b": {2}}"#, color);
        let binding = msg.as_str();

        self.send_message(binding);
    }

    pub fn set_one(&mut self, color: RGB, index: u32) {
        if self.number_of_leds < index
            {panic!("You give me an index greater than what you set as!");}
        let msg = self.replace_with_color(r#"{"command": 1, "r": {0}, "g": {1}, "b": {2}, "index": {3}}"#, color);
        let index_replace = msg.replace("{3}", index.to_string().as_str());
        let binding = index_replace.as_str();

        self.send_message(binding);
    }

    
    pub fn set_list(&mut self, colors: Vec<RGB>)  {
        // xxx: this could be extremely inefficient, but this will work for now.
        let mut list_replace: Vec<String> = vec![];
        for rgb in colors {
            list_replace.push(rgb.to_string());
        }
        
        let msg = r#"{"command": 2, "rgb_list": [{0}]}"#.replace("{0}", &list_replace.join(", ").replace("(", "[").replace(")", "]"));
        let binding = msg.as_str();

        self.send_message(binding);
    }
}