|
@@ -1,4 +1,10 @@
|
|
|
-pub mod tcp_code;
|
|
|
+pub mod code;
|
|
|
+
|
|
|
+pub trait BaseModbusCode {
|
|
|
+ fn addr(&self) -> Option<u16>;
|
|
|
+}
|
|
|
+
|
|
|
+const MAX_REGISTER_COUNT: usize = 120;
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
pub enum ModbusDataType {
|
|
@@ -6,3 +12,78 @@ pub enum ModbusDataType {
|
|
|
U16,
|
|
|
S16,
|
|
|
}
|
|
|
+
|
|
|
+/// 将序列按照连续子序列分割出来
|
|
|
+/// 如: [1,3,2,7,8,11,10] 分割为 [[1,2,3],[7,8],[10,11]]
|
|
|
+pub fn sequential<T: BaseModbusCode>(mut codes: Vec<T>) -> Vec<Vec<T>> {
|
|
|
+ //按地址升序排序
|
|
|
+ codes.sort_by(|a, b| a.addr().cmp(&b.addr()));
|
|
|
+ if codes.is_empty() {
|
|
|
+ return Vec::new();
|
|
|
+ }
|
|
|
+ let mut vec = Vec::new();
|
|
|
+ let mut current_group = Vec::new();
|
|
|
+ let mut iter = codes.into_iter();
|
|
|
+ if let Some(prev) = iter.next() {
|
|
|
+ current_group.push(prev);
|
|
|
+ for current in iter {
|
|
|
+ if let Some(prev) = current_group.last() {
|
|
|
+ if let Some(prev_addr) = prev.addr() {
|
|
|
+ if let Some(curr_addr) = current.addr() {
|
|
|
+ if prev_addr + 1 == curr_addr {
|
|
|
+ if current_group.len() >= MAX_REGISTER_COUNT {
|
|
|
+ vec.push(current_group);
|
|
|
+ current_group = Vec::new();
|
|
|
+ }
|
|
|
+ current_group.push(current);
|
|
|
+ } else {
|
|
|
+ vec.push(current_group);
|
|
|
+ current_group = Vec::new();
|
|
|
+ current_group.push(current)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ vec.push(current_group);
|
|
|
+ }
|
|
|
+ vec
|
|
|
+}
|
|
|
+
|
|
|
+mod test {
|
|
|
+ use super::*;
|
|
|
+
|
|
|
+ #[derive(Debug)]
|
|
|
+ struct TestModbusCode {
|
|
|
+ addr: Option<u16>,
|
|
|
+ }
|
|
|
+
|
|
|
+ impl BaseModbusCode for TestModbusCode {
|
|
|
+ fn addr(&self) -> Option<u16> {
|
|
|
+ self.addr
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_sequential() {
|
|
|
+ let base = TestModbusCode { addr: Some(1u16) };
|
|
|
+ let vec = sequential(vec![
|
|
|
+ base,
|
|
|
+ TestModbusCode { addr: Some(3u16) },
|
|
|
+ TestModbusCode { addr: Some(2u16) },
|
|
|
+ TestModbusCode { addr: Some(7u16) },
|
|
|
+ TestModbusCode { addr: Some(8u16) },
|
|
|
+ TestModbusCode { addr: Some(11u16) },
|
|
|
+ TestModbusCode { addr: Some(10u16) },
|
|
|
+ ]);
|
|
|
+ let vec = vec
|
|
|
+ .into_iter()
|
|
|
+ .map(|it| {
|
|
|
+ it.into_iter()
|
|
|
+ .map(|i| i.addr.unwrap())
|
|
|
+ .collect::<Vec<u16>>()
|
|
|
+ })
|
|
|
+ .collect::<Vec<Vec<u16>>>();
|
|
|
+ assert_eq!(vec, vec![vec![1, 2, 3], vec![7, 8], vec![10, 11],]);
|
|
|
+ }
|
|
|
+}
|