Add message builder
This commit is contained in:
parent
5ec6ace462
commit
efbad0d676
5 changed files with 120 additions and 55 deletions
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -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 => (),
|
||||
}
|
||||
}
|
||||
|
|
65
src/service_specific/message_builder.rs
Normal file
65
src/service_specific/message_builder.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
5
src/service_specific/mod.rs
Normal file
5
src/service_specific/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod message_builder;
|
||||
mod port;
|
||||
|
||||
pub use message_builder::*;
|
||||
pub use port::*;
|
|
@ -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))?;
|
||||
|
Loading…
Reference in a new issue