light_cli/output.rs
1use core;
2
3use nb;
4use hal::serial::Write;
5
6use heapless::consts::*;
7use heapless::spsc::Queue;
8
9pub struct LightCliOutput<'a, E: 'a> {
10 rb: Queue<u8, U128>,
11 writer: &'a mut Write<u8, Error=E>
12}
13
14impl<'a, E> core::fmt::Write for LightCliOutput<'a, E> {
15 fn write_str(&mut self, s: &str) -> core::fmt::Result {
16 for c in s.as_bytes() {
17 loop {
18 if self.rb.enqueue(c.clone()).is_ok() {
19 break;
20 } else {
21 match self.flush() {
22 Err(nb::Error::Other(_)) => return Err(core::fmt::Error),
23 _ => () // otherwise either non blocking or ok, so try to repeat
24 }
25 }
26 }
27 }
28 Ok(())
29 }
30}
31
32impl<'a, E> LightCliOutput<'a, E> {
33 /// Creates a now buffered console output instance.
34 ///
35 /// # Arguments
36 /// * `writer`: The serial output instance, implementing the [`Write<u8>`] interface.
37 ///
38 /// [`Write<u8>`]: ../embedded_hal/serial/trait.Write.html
39 pub fn new(writer: &'a mut Write<u8, Error = E>) -> Self {
40 Self {
41 rb: Queue::new(),
42 writer: writer
43 }
44 }
45
46 fn peek(&self) -> Option<u8> {
47 match self.rb.iter().next() {
48 None => None,
49 Some(v) => Some(v.clone())
50 }
51 }
52
53 /// Tries to send as many characters as it can until the interface
54 /// starts blocking or there are no charactors to submit.
55 ///
56 /// # Remarks
57 ///
58 /// If the function returns Ok, then the buffer has succesfully been flushed
59 /// whereas the error `WouldBlock` indicates that it is not empty
60 /// but would have blocked if it tried to submit the character.
61 ///
62 /// To completely empty the buffer, use `block!(cl_output.flush()).unwrap()`.
63 pub fn flush(&mut self) -> nb::Result<(), E> {
64 let mut co = self.peek();
65
66 loop {
67 match co {
68 None => return Ok(()),
69 Some(c) => {
70 let res = self.writer.write(c.clone());
71 match res {
72 Err(nb::Error::WouldBlock) => return Err(nb::Error::WouldBlock),
73 Err(nb::Error::Other(o)) => return Err(nb::Error::Other(o)),
74 Ok(()) => {
75 self.rb.dequeue().unwrap();
76 co = self.peek();
77 },
78 }
79 }
80 }
81 }
82 }
83}