Add message builder

This commit is contained in:
hodasemi 2019-11-24 15:54:36 +01:00
parent 5ec6ace462
commit efbad0d676
5 changed files with 120 additions and 55 deletions

View file

@ -20,22 +20,6 @@ struct Button {
const int button_count = 8;
const Button buttons[button_count] = {
{
.pin_id = 2,
.last_state = LOW
},
{
.pin_id = 3,
.last_state = LOW
},
{
.pin_id = 4,
.last_state = LOW
},
{
.pin_id = 5,
.last_state = LOW
},
{
.pin_id = 6,
.last_state = LOW
@ -51,6 +35,22 @@ const Button buttons[button_count] = {
{
.pin_id = 9,
.last_state = LOW
},
{
.pin_id = 10,
.last_state = LOW
},
{
.pin_id = 11,
.last_state = LOW
},
{
.pin_id = 12,
.last_state = LOW
},
{
.pin_id = 13,
.last_state = LOW
}
};
@ -98,43 +98,35 @@ void check_pin(Button* button, byte index) {
if (button->last_state == LOW) {
button->last_state = HIGH;
send_message("HIGH");
/*
// assemble message
Serial.print(message_start);
Serial.print(index + 1);
Serial.print(message_end);
// force new line
Serial.print('\n');
*/
debug_message(button->pin_id, "HIGH");
}
} else {
if (button->last_state == HIGH) {
button->last_state = LOW;
send_message("LOW");
debug_message(button->pin_id, "LOW");
}
}
}
void send_message(char c) {
void debug_message(byte pin_id, char c[]) {
// assemble message
Serial.print(message_start);
Serial.print(pin_id);
Serial.print(' ');
Serial.print(c);
Serial.print(message_end);
// force new line
Serial.print('\n');
}
void send_message(char c[]) {
// assemble message
Serial.print(message_start);
Serial.print(c);
Serial.print(message_end);
// force new line
Serial.print('\n');
}
void send_message(byte b) {
// assemble message
Serial.print(message_start);
Serial.print(b);
Serial.print(message_end);
// force new line
Serial.print('\n');
}

View file

@ -1,24 +1,31 @@
mod port;
mod service_specific;
use service_specific::*;
use utilities::prelude::*;
use port::*;
fn main() -> VerboseResult<()> {
let settings = SerialPortSettings {
let mut port = Port::open(SerialPortSettings {
baud_rate: 9600,
data_bits: DataBits::Eight,
parity: Parity::None,
stop_bits: StopBits::One,
flow_control: FlowControl::None,
timeout: Duration::from_millis(2500),
};
})?;
let port = Port::open(settings)?;
let mut message_builder = MessageBuilder::default();
loop {
match port.read()? {
SerialReadResult::Message(msg) => println!("{}", msg),
SerialReadResult::Message(msg) => {
if let Some(remaining) = message_builder.check(msg) {
assert!(message_builder.is_complete());
println!("{}", message_builder.message());
message_builder = MessageBuilder::default();
}
}
SerialReadResult::Timeout => (),
}
}

View file

@ -0,0 +1,65 @@
const MESSAGE_START: char = '<';
const MESSAGE_END: char = '>';
#[derive(Debug)]
pub struct MessageBuilder {
message: String,
complete: bool,
started: bool,
}
impl MessageBuilder {
pub fn check(&mut self, mut msg: String) -> Option<String> {
// if message hasn't started, search for message start token
if !self.started {
let token_position = match msg.chars().position(|c| c == MESSAGE_START) {
Some(position) => position,
None => return None,
};
msg = msg.split_off(token_position + 1);
self.started = true;
}
if !self.complete {
match msg.chars().position(|c| c == MESSAGE_END) {
Some(position) => {
let mut remaining_msg = msg.split_off(position);
self.message.push_str(&msg);
self.complete = true;
msg = remaining_msg;
}
None => {
self.message.push_str(&msg);
msg.clear();
}
};
}
if msg.is_empty() {
None
} else {
Some(msg)
}
}
pub fn is_complete(&self) -> bool {
self.complete
}
pub fn message(&self) -> &str {
&self.message
}
}
impl Default for MessageBuilder {
fn default() -> MessageBuilder {
MessageBuilder {
message: String::new(),
complete: false,
started: false,
}
}
}

View file

@ -0,0 +1,5 @@
mod message_builder;
mod port;
pub use message_builder::*;
pub use port::*;

View file

@ -3,7 +3,6 @@ use serialport::prelude::*;
use utilities::prelude::*;
use std::cell::RefCell;
use std::io;
pub use serialport::{DataBits, FlowControl, Parity, SerialPortSettings, StopBits};
@ -15,7 +14,7 @@ pub enum SerialReadResult {
}
pub struct Port {
serial_port: RefCell<Box<dyn SerialPort>>,
serial_port: Box<dyn SerialPort>,
}
impl Port {
@ -31,16 +30,14 @@ impl Port {
)
})?;
Ok(Port {
serial_port: RefCell::new(port),
})
Ok(Port { serial_port: port })
}
#[allow(unused)]
pub fn read(&self) -> VerboseResult<SerialReadResult> {
pub fn read(&mut self) -> VerboseResult<SerialReadResult> {
let mut buf: Vec<u8> = (0..255).collect();
match self.serial_port.try_borrow_mut()?.read(&mut buf[..]) {
match self.serial_port.read(&mut buf[..]) {
Ok(t) => Ok(SerialReadResult::Message(
String::from_utf8(buf[0..t].to_vec())
.map_err(|err| format!("failed converting utf8 buffer ({})", err))?,
@ -51,9 +48,8 @@ impl Port {
}
#[allow(unused)]
pub fn write(&self, msg: &str) -> VerboseResult<()> {
pub fn write(&mut self, msg: &str) -> VerboseResult<()> {
self.serial_port
.try_borrow_mut()?
.write(msg.as_bytes())
.map_err(|err| format!("failed writing to serial port ({})", err))?;