cobs/lib.rs
1//! # `cobs`
2//!
3//! This is an implementation of the Consistent Overhead Byte Stuffing (COBS) algorithm in Rust.
4//!
5//! COBS is an algorithm for transforming a message into an encoding where a specific value (the
6//! "sentinel" value) is not used. This value can then be used to mark frame boundaries in a serial
7//! communication channel.
8//!
9//! See the [wikipedia article](https://www.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing) for details.
10//!
11//! ## Features
12//!
13//! `cobs` supports various runtime environments and is also suitable for `no_std` environments.
14//!
15//! ### Default features
16//!
17//! - [`std`](https://doc.rust-lang.org/std/): Enables functionality relying on the standard library
18//!   and also activates the `alloc` feature. Currently only adds [std::error::Error] support for the
19//!   library error types.
20//! - [`alloc`](https://doc.rust-lang.org/alloc/): Enables features which operate on containers
21//!   like [alloc::vec::Vec](https://doc.rust-lang.org/beta/alloc/vec/struct.Vec.html).
22//!   Enabled by the `std` feature.
23//!
24//! ### Optional features
25//!
26//! - [`defmt`](https://docs.rs/defmt/latest/defmt/): Adds `defmt::Format` derives on some data
27//!   structures and error types.
28//! - [`serde`](https://serde.rs/): Adds `serde` derives on some data structures and error types.
29#![no_std]
30#![cfg_attr(docsrs, feature(doc_auto_cfg))]
31#[cfg(feature = "alloc")]
32extern crate alloc;
33#[cfg(feature = "std")]
34extern crate std;
35
36// In the future, don't do this.
37mod dec;
38mod enc;
39pub use crate::dec::*;
40pub use crate::enc::*;
41
42/// Calculates the maximum overhead when encoding a message with the given length.
43/// The overhead is a maximum of [n/254] bytes (one in 254 bytes) rounded up.
44#[inline]
45pub const fn max_encoding_overhead(source_len: usize) -> usize {
46    source_len.div_ceil(254)
47}
48
49/// Calculates the maximum possible size of an encoded message given the length
50/// of the source message. This may be useful for calculating how large the
51/// `dest` buffer needs to be in the encoding functions.
52#[inline]
53pub const fn max_encoding_length(source_len: usize) -> usize {
54    source_len + max_encoding_overhead(source_len)
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    // Usable in const context
62    const ENCODED_BUF: [u8; max_encoding_length(5)] = [0; max_encoding_length(5)];
63
64    #[test]
65    fn test_buf_len() {
66        assert_eq!(ENCODED_BUF.len(), 6);
67    }
68
69    #[test]
70    fn test_overhead_empty() {
71        assert_eq!(max_encoding_overhead(0), 0);
72    }
73
74    #[test]
75    fn test_overhead_one() {
76        assert_eq!(max_encoding_overhead(1), 1);
77    }
78
79    #[test]
80    fn test_overhead_larger() {
81        assert_eq!(max_encoding_overhead(253), 1);
82        assert_eq!(max_encoding_overhead(254), 1);
83    }
84
85    #[test]
86    fn test_overhead_two() {
87        assert_eq!(max_encoding_overhead(255), 2);
88    }
89}