1use std::io::prelude::*;
17use std::os::unix::net::UnixStream;
18use std::io;
19
20const BRIGHTNESS: u8 = 0;
21const SET_PIXEL: u8 = 1;
22const SET_ALL_PIXELS: u8 = 2;
23const SHOW: u8 = 3;
24
25#[repr(C,packed)]
26#[derive(Copy,Clone)]
27pub struct Pos {
28 pub x: u8,
29 pub y: u8
30}
31
32#[repr(C,packed)]
33#[derive(Copy,Clone)]
34pub struct Pixel {
35 pub g: u8,
36 pub r: u8,
37 pub b: u8
38}
39
40#[repr(C,packed)]
41struct SetBrightnessCmd{
42 code: u8,
43 brightness: u8
44}
45
46#[repr(C,packed)]
47struct SetPixelCmd {
48 code: u8,
49 pos: Pos,
50 col: Pixel
51}
52
53#[repr(C,packed)]
54struct SetAllPixelsCmd {
55 code: u8,
56 pixels: [Pixel; 64]
57}
58
59pub struct UnicorndClient {
60 sd: UnixStream
61}
62
63impl UnicorndClient {
64 pub fn new(path: String) -> Option<Self> {
65 let p = path.clone();
66 let sd = match UnixStream::connect(path) {
67 Ok(sd) => sd,
68 Err(e) => {
69 eprintln!("Cannot connect to {}: {}", p, e);
70 return None
71 },
72 };
73
74 return Some(UnicorndClient{sd});
75 }
76
77 pub fn set_brightness(&mut self, brightness: u8) -> io::Result<()> {
78 self.write(&SetBrightnessCmd{
79 code: BRIGHTNESS,
80 brightness: brightness
81 })
82 }
83
84 pub fn set_pixel(&mut self, pos: Pos, col: Pixel) -> io::Result<()> {
85 self.write(&SetPixelCmd{
86 code: SET_PIXEL,
87 pos: pos,
88 col: col
89 })
90 }
91
92 pub fn set_all_pixels(&mut self, pixels: [Pixel; 64]) -> io::Result<()> {
93 self.write(&SetAllPixelsCmd{
94 code: SET_ALL_PIXELS,
95 pixels: pixels
96 })
97 }
98
99 pub fn show(&mut self) -> io::Result<()> {
100 self.write(&SHOW)
101 }
102
103 fn write<T: Sized>(&mut self, p: &T) -> io::Result<()> {
104 let buf = unsafe {
105 ::std::slice::from_raw_parts(
106 (p as *const T) as *const u8,
107 ::std::mem::size_of::<T>()
108 )
109 };
110
111 self.sd.write_all(buf)
112 }
113}