use std::{time::{Duration, Instant}, thread, io};
use fiscalprinter::{FiscalPrinterDriver};
use serialport::SerialPort;
use fiscalprinter::Result;
use rand::Rng;
#[derive(Clone, Copy)]
pub struct Driver {
_last_sequence: u8
}
const MINIMUM_SEQUENCE: u8 = 32;
const MAXIMUM_SEQUENCE: u8 = 127;
const ASCII_START_CHARACTER: u8 = 2;
const ASCII_END_CHARACTER: u8 = 3;
impl Driver {
fn next_sequence(mut self) -> u8 {
self._last_sequence = rand::thread_rng().gen_range(MINIMUM_SEQUENCE..MAXIMUM_SEQUENCE);
self._last_sequence
}
fn checksum(msg: &[u8]) -> String {
let mut crc: u16 = 0x0;
for hex in msg.iter() {
let hex_cloned = hex.clone();
crc = crc + (hex_cloned as u16);
}
let mut checksum_as_hex_value = format!("{:X}", crc);
checksum_as_hex_value = format!("{:0>4}", checksum_as_hex_value);
checksum_as_hex_value
}
fn build_command(self, command: Vec<u8>) -> Result<Vec<u8>> {
let start_value = [
ASCII_START_CHARACTER,
self.next_sequence()
];
let end_value: &[u8] = &[ASCII_END_CHARACTER];
let start_value: &[u8] = &start_value;
let _command: &[u8] = &command;
let value = [start_value, _command, end_value].concat();
let checksum_value = Driver::checksum(&value);
let checksum_value: &[u8] = &checksum_value.as_bytes();
let value: &[u8] = &value;
let command_to_print = [value, checksum_value].concat();
return Ok(command_to_print);
}
}
impl FiscalPrinterDriver for Driver {
fn new() -> Self {
Driver {
_last_sequence: MINIMUM_SEQUENCE
}
}
fn send_command(&mut self, mut _handler: &mut Box<dyn SerialPort>, _command: Vec<u8>) -> Result<bool> {
println!("send_command {:?}" , _command);
let _complete_command = self.build_command(_command).expect("Error with command");
let _complete_command: &[u8] = &_complete_command;
println!("complete command {:?}", _complete_command);
_handler.write(_complete_command).expect("error writing on port");
let _result = self.read(_handler).expect("Error reading port");
Ok(_result.len() > 0)
}
fn read(&mut self, mut _handler: &mut Box<dyn SerialPort>) -> Result<Vec<u8>> {
let time = Instant::now();
let mut _result: Vec<u8> = vec![0; 1000];
let mut _size = 0;
loop {
thread::sleep(Duration::from_millis(10));
match _handler.read(_result.as_mut_slice()) {
Ok(t) => {
_size = t;
},
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => eprintln!("{:?}", e),
}
match time.elapsed() {
t if t.as_millis() > 100 => break,
_ => {
}
}
}
let mut _final_result: Vec<u8> = vec![0; 0];
if _size > 0 {
_final_result = _result[.._size].to_vec();
println!("Result {:?}", _final_result);
}
Ok(_final_result)
}
}