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
78
79
80
81
82
83
use core;
use nb;
use hal::serial::Write;
use heapless::consts::*;
use heapless::spsc::Queue;
pub struct LightCliOutput<'a, E: 'a> {
rb: Queue<u8, U128>,
writer: &'a mut Write<u8, Error=E>
}
impl<'a, E> core::fmt::Write for LightCliOutput<'a, E> {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
for c in s.as_bytes() {
loop {
if self.rb.enqueue(c.clone()).is_ok() {
break;
} else {
match self.flush() {
Err(nb::Error::Other(_)) => return Err(core::fmt::Error),
_ => ()
}
}
}
}
Ok(())
}
}
impl<'a, E> LightCliOutput<'a, E> {
pub fn new(writer: &'a mut Write<u8, Error = E>) -> Self {
Self {
rb: Queue::new(),
writer: writer
}
}
fn peek(&self) -> Option<u8> {
match self.rb.iter().next() {
None => None,
Some(v) => Some(v.clone())
}
}
pub fn flush(&mut self) -> nb::Result<(), E> {
let mut co = self.peek();
loop {
match co {
None => return Ok(()),
Some(c) => {
let res = self.writer.write(c.clone());
match res {
Err(nb::Error::WouldBlock) => return Err(nb::Error::WouldBlock),
Err(nb::Error::Other(o)) => return Err(nb::Error::Other(o)),
Ok(()) => {
self.rb.dequeue().unwrap();
co = self.peek();
},
}
}
}
}
}
}