Skip to main content

ps_ecc/long/header/methods/
segment_count.rs

1use crate::long::LongEccHeader;
2
3impl LongEccHeader {
4    /// Number of segments: every segment before the last contributes
5    /// `segment_distance - 2 * parity` new data bytes, and the final, shorter
6    /// segment covers the remainder.
7    ///
8    /// The constructors enforce `2 * parity < segment_distance`, so the
9    /// subtraction cannot underflow.
10    #[inline]
11    #[must_use]
12    pub const fn segment_count(&self) -> u32 {
13        let new_bytes_per_segment = (self.segment_distance() - self.parity_bytes()) as u32;
14        let remaining_bytes = self
15            .message_length()
16            .saturating_sub(self.segment_length() as u32 - 1);
17
18        remaining_bytes
19            .div_ceil(new_bytes_per_segment)
20            .saturating_add(1)
21    }
22}
23
24#[cfg(test)]
25mod tests {
26    use crate::long::{LongEccHeader, OverlapFactor};
27
28    type TestError = Box<dyn std::error::Error>;
29
30    #[test]
31    fn test_segment_count_single_segment() -> Result<(), TestError> {
32        let header = LongEccHeader::new(2, OverlapFactor::Simple, 136, 100, 0)?;
33
34        assert_eq!(header.segment_count(), 1);
35
36        Ok(())
37    }
38
39    #[test]
40    fn test_segment_count_empty_message() -> Result<(), TestError> {
41        let header = LongEccHeader::new(2, OverlapFactor::Simple, 36, 0, 0)?;
42
43        assert_eq!(header.segment_count(), 1);
44
45        Ok(())
46    }
47
48    #[test]
49    fn test_segment_count_multiple_segments() -> Result<(), TestError> {
50        // With parity 4, a segment holds 247 data bytes and each full segment
51        // contributes 239 new bytes, so 600 bytes require three segments.
52        let header = LongEccHeader::new(4, OverlapFactor::Simple, 656, 600, 0)?;
53
54        assert_eq!(header.segment_count(), 3);
55
56        Ok(())
57    }
58
59    #[test]
60    fn test_segment_count_boundary_at_segment_length() -> Result<(), TestError> {
61        // With parity 4, a segment holds 247 data bytes: a 246-byte message
62        // fits in one segment, and a 247-byte message spills into a second.
63        let single = LongEccHeader::new(4, OverlapFactor::Simple, 286, 246, 0)?;
64        let double = LongEccHeader::new(4, OverlapFactor::Simple, 295, 247, 0)?;
65
66        assert_eq!(single.segment_count(), 1);
67        assert_eq!(double.segment_count(), 2);
68
69        Ok(())
70    }
71}