|
@@ -13,7 +13,36 @@ pub enum ModbusDataType {
|
|
|
S16,
|
|
|
}
|
|
|
|
|
|
-/// 将序列按照连续子序列分割出来
|
|
|
+/// 将序列按照连续子序列分组
|
|
|
+/// 如: [1,3,2,7,8,11,10] 分割为 [[1,2,3],[7,8],[10,11]]
|
|
|
+pub fn slice_sequential<T>(codes: &mut [T]) -> Vec<&mut [T]>
|
|
|
+where
|
|
|
+ T: BaseModbusCode,
|
|
|
+{
|
|
|
+ codes.sort_by(|a, b| a.addr().cmp(&b.addr()));
|
|
|
+ let mut result = Vec::new();
|
|
|
+ let mut remaining = codes;
|
|
|
+ while !remaining.is_empty() {
|
|
|
+ let mut len = 1;
|
|
|
+ while len < remaining.len() {
|
|
|
+ if let (Some(prev_addr), Some(curr_addr)) =
|
|
|
+ (remaining[len - 1].addr(), remaining[len].addr())
|
|
|
+ {
|
|
|
+ if prev_addr + 1 == curr_addr && len < MAX_REGISTER_COUNT {
|
|
|
+ len += 1;
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let (group, rest) = remaining.split_at_mut(len);
|
|
|
+ result.push(group);
|
|
|
+ remaining = rest;
|
|
|
+ }
|
|
|
+ result
|
|
|
+}
|
|
|
+
|
|
|
+/// 将序列按照连续子序列分组
|
|
|
/// 如: [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>> {
|
|
|
//按地址升序排序
|
|
@@ -50,39 +79,34 @@ pub fn sequential<T: BaseModbusCode>(mut codes: Vec<T>) -> Vec<Vec<T>> {
|
|
|
vec
|
|
|
}
|
|
|
|
|
|
+#[cfg(test)]
|
|
|
mod test {
|
|
|
use super::*;
|
|
|
|
|
|
- #[derive(Debug)]
|
|
|
- struct TestModbusCode {
|
|
|
- addr: Option<u16>,
|
|
|
- }
|
|
|
+ struct TestModbusCode(Option<u16>);
|
|
|
|
|
|
impl BaseModbusCode for TestModbusCode {
|
|
|
fn addr(&self) -> Option<u16> {
|
|
|
- self.addr
|
|
|
+ self.0
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
|
fn test_sequential() {
|
|
|
- let base = TestModbusCode { addr: Some(1u16) };
|
|
|
- let vec = sequential(vec![
|
|
|
+ let base = TestModbusCode { 0: Some(1u16) };
|
|
|
+ let mut codes = 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) },
|
|
|
- ]);
|
|
|
+ TestModbusCode { 0: Some(3u16) },
|
|
|
+ TestModbusCode { 0: Some(2u16) },
|
|
|
+ TestModbusCode { 0: Some(7u16) },
|
|
|
+ TestModbusCode { 0: Some(8u16) },
|
|
|
+ TestModbusCode { 0: Some(11u16) },
|
|
|
+ TestModbusCode { 0: Some(10u16) },
|
|
|
+ ];
|
|
|
+ let vec = slice_sequential(codes.as_mut_slice());
|
|
|
let vec = vec
|
|
|
.into_iter()
|
|
|
- .map(|it| {
|
|
|
- it.into_iter()
|
|
|
- .map(|i| i.addr.unwrap())
|
|
|
- .collect::<Vec<u16>>()
|
|
|
- })
|
|
|
+ .map(|it| it.into_iter().map(|i| i.0.unwrap()).collect::<Vec<u16>>())
|
|
|
.collect::<Vec<Vec<u16>>>();
|
|
|
assert_eq!(vec, vec![vec![1, 2, 3], vec![7, 8], vec![10, 11],]);
|
|
|
}
|