#[cfg(feature = "alloc")]
use alloc::vec;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
pub const MAX_LENGTH: usize = usize::BITS as usize - 1;
pub const MAX_SEQUENCE: usize = usize::MAX - 1;
pub fn decode_len(s: usize) -> usize {
debug_assert!(s <= MAX_SEQUENCE, "Failed precondition");
MAX_LENGTH - (s + 1).leading_zeros() as usize
}
#[test]
fn decode_len_ok() {
fn test(s: usize, n: usize) {
assert_eq!(decode_len(s), n, "s={s}");
}
test(0, 0);
test(1, 1);
test(2, 1);
test(3, 2);
test(6, 2);
test(7, 3);
test(14, 3);
}
pub fn decode_mut(s: usize, xs: &mut [bool]) {
debug_assert!(s <= MAX_SEQUENCE, "Failed precondition");
let n = decode_len(s);
debug_assert_eq!(xs.len(), n, "Failed precondition");
for (i, x) in xs.iter_mut().rev().enumerate() {
*x = (s + 1) & 1 << i != 0;
}
}
#[cfg(feature = "alloc")]
pub fn decode(s: usize) -> Vec<bool> {
let n = decode_len(s);
let mut xs = vec![false; n];
decode_mut(s, &mut xs);
xs
}
#[test]
fn decode_ok() {
fn test(s: usize, xs: &[bool]) {
assert_eq!(decode(s), xs, "s={s} xs={xs:?}");
}
test(0, &[]);
test(1, &[false]);
test(2, &[true]);
test(3, &[false, false]);
test(4, &[false, true]);
test(5, &[true, false]);
test(6, &[true, true]);
test(7, &[false, false, false]);
test(8, &[false, false, true]);
test(9, &[false, true, false]);
test(10, &[false, true, true]);
test(11, &[true, false, false]);
test(12, &[true, false, true]);
test(13, &[true, true, false]);
test(14, &[true, true, true]);
}
pub fn encode(xs: &[bool]) -> usize {
debug_assert!(xs.len() <= MAX_LENGTH, "Failed precondition");
let mut s = 0;
for &x in xs {
s = 2 * s + 1 + x as usize;
}
s
}
#[test]
fn encode_ok() {
fn test(xs: &[bool], s: usize) {
assert_eq!(encode(xs), s, "xs={xs:?}");
}
test(&[], 0);
test(&[false], 1);
test(&[true], 2);
test(&[false, false], 3);
test(&[false, true], 4);
test(&[true, false], 5);
test(&[true, true], 6);
test(&[false, false, false], 7);
test(&[false, false, true], 8);
test(&[false, true, false], 9);
test(&[false, true, true], 10);
test(&[true, false, false], 11);
test(&[true, false, true], 12);
test(&[true, true, false], 13);
test(&[true, true, true], 14);
}