sbf_tools/blocks/
differential.rs1use crate::error::{SbfError, SbfResult};
4use crate::header::SbfHeader;
5
6use super::block_ids;
7use super::SbfBlockParse;
8
9#[derive(Debug, Clone)]
17pub struct DiffCorrInBlock {
18 tow_ms: u32,
19 wnc: u16,
20 pub mode: u8,
22 pub source: u8,
24 pub message_content: Vec<u8>,
26}
27
28impl DiffCorrInBlock {
29 pub fn tow_seconds(&self) -> f64 {
30 self.tow_ms as f64 * 0.001
31 }
32 pub fn tow_ms(&self) -> u32 {
33 self.tow_ms
34 }
35 pub fn wnc(&self) -> u16 {
36 self.wnc
37 }
38}
39
40impl SbfBlockParse for DiffCorrInBlock {
41 const BLOCK_ID: u16 = block_ids::DIFF_CORR_IN;
42
43 fn parse(header: &SbfHeader, data: &[u8]) -> SbfResult<Self> {
44 const MIN_LEN: usize = 14;
45 if data.len() < MIN_LEN {
46 return Err(SbfError::ParseError("DiffCorrIn too short".into()));
47 }
48
49 let mode = data[12];
50 let source = data[13];
51 let message_content = data[14..].to_vec();
52
53 Ok(Self {
54 tow_ms: header.tow_ms,
55 wnc: header.wnc,
56 mode,
57 source,
58 message_content,
59 })
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn test_diff_corr_in_parse() {
69 let header = SbfHeader {
70 crc: 0,
71 block_id: block_ids::DIFF_CORR_IN,
72 block_rev: 0,
73 length: 20,
74 tow_ms: 5000,
75 wnc: 2100,
76 };
77 let mut data = vec![0u8; 20];
78 data[0..2].copy_from_slice(&0u16.to_le_bytes());
79 data[2..4].copy_from_slice(&block_ids::DIFF_CORR_IN.to_le_bytes());
80 data[4..6].copy_from_slice(&20u16.to_le_bytes());
81 data[6..10].copy_from_slice(&5000u32.to_le_bytes());
82 data[10..12].copy_from_slice(&2100u16.to_le_bytes());
83 data[12] = 1; data[13] = 2; data[14..18].copy_from_slice(&[0xD3, 0x00, 0x13, 0x40]); let block = DiffCorrInBlock::parse(&header, &data).unwrap();
88 assert_eq!(block.tow_ms(), 5000);
89 assert_eq!(block.wnc(), 2100);
90 assert_eq!(block.tow_seconds(), 5.0);
91 assert_eq!(block.mode, 1);
92 assert_eq!(block.source, 2);
93 assert_eq!(block.message_content.len(), 6);
94 assert_eq!(block.message_content[0], 0xD3);
95 }
96
97 #[test]
98 fn test_diff_corr_in_dnu_empty_message() {
99 let header = SbfHeader {
100 crc: 0,
101 block_id: block_ids::DIFF_CORR_IN,
102 block_rev: 0,
103 length: 14,
104 tow_ms: 0,
105 wnc: 0,
106 };
107 let mut data = vec![0u8; 14];
108 data[12] = 0;
109 data[13] = 0;
110
111 let block = DiffCorrInBlock::parse(&header, &data).unwrap();
112 assert!(block.message_content.is_empty());
113 }
114}