rust-s7-datatypes/src/types/uint.rs

82 lines
2.4 KiB
Rust
Raw Normal View History

2021-10-16 15:17:09 +00:00
use anyhow::Result;
use serde::{Deserialize, Serialize};
use super::super::errors::*;
use super::super::sps_datatypes::{BitPosition, DataEvaluation, UnparsedSPSDataType};
#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)]
2021-10-16 15:17:09 +00:00
pub struct UIntType {
length: u32,
position: BitPosition,
}
impl UIntType {
const LEN: usize = 2;
2021-10-22 15:59:36 +00:00
pub fn new(byte: u32, bit: Option<u32>) -> Result<Self, Errors> {
Ok(UIntType {
length: Self::LEN as u32,
position: BitPosition { byte, bit },
})
2021-10-16 15:17:09 +00:00
}
}
impl DataEvaluation for UIntType {
fn into_unparsed(&self) -> UnparsedSPSDataType {
UnparsedSPSDataType {
data_type: self.into_string(),
data_byte: self.position.byte,
data_bit: self.position.bit,
data_length: None,
}
}
2021-11-09 20:32:53 +00:00
fn into_string(&self) -> String {
"uint".to_string()
}
2021-10-16 15:17:09 +00:00
fn get_end_byte(&self) -> u32 {
self.position.byte + self.length
}
fn get_byte_positon(&self) -> u32 {
self.position.byte
}
fn get_length(&self) -> u32 {
self.length
}
fn parse_serial(&self, data: &[&str]) -> Result<String> {
Ok(data
.get((self.position.byte) as usize)
.ok_or_else(|| serial_error(self.into_string(), self.position.byte))?
.to_string())
}
fn parse_s7(&self, data: &[u8]) -> Result<String> {
let bytes = data
.get((self.position.byte) as usize..(self.position.byte + self.length) as usize)
.ok_or_else(|| s7_read_error(self.into_string(), self.position.byte))?;
let mut slice: [u8; Self::LEN] = Default::default();
slice.copy_from_slice(bytes);
let parsed = u16::from_be_bytes(slice);
Ok(parsed.to_string())
}
fn sql_equivalent(&self) -> &str {
r"INT UNSIGNED DEFAULT 0"
}
}
#[test]
fn test() {
const INTPOS: u32 = 15;
const INT: u16 = 8209;
const LEN: usize = 2;
2021-10-22 15:59:36 +00:00
let test_item = UIntType::new(INTPOS, None).unwrap();
2021-10-16 15:17:09 +00:00
let raw_data: [u8; 50] = [255; 50];
let mut test_vec: Vec<u8> = raw_data.to_vec();
test_vec.splice(
INTPOS as usize..INTPOS as usize + LEN,
INT.to_be_bytes().iter().cloned(),
);
let result = match test_item.parse_s7(&test_vec) {
Ok(res) => res,
Err(_) => "Error".to_string(),
};
assert_eq!(result, INT.to_string())
}