use std::collections::VecDeque;
use std::error::Error;
use std::fmt;
use super::bitset::BitSetBuilder;
use super::input_bit_stream::InputBitStream;
use super::output_bit_stream::OutputBitStream;
use super::BitSet;
use super::IntSet;
#[derive(Debug, PartialEq)]
pub struct DecodingError;
impl Error for DecodingError {}
impl fmt::Display for DecodingError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"The input data stream was too short to be a valid sparse bit set."
)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub(crate) enum BranchFactor {
Two,
Four,
Eight,
ThirtyTwo,
}
impl IntSet<u32> {
pub fn from_sparse_bit_set(data: &[u8]) -> Result<IntSet<u32>, DecodingError> {
Self::from_sparse_bit_set_bounded(data, 0, u32::MAX).map(|(set, _)| set)
}
pub fn from_sparse_bit_set_bounded(
data: &[u8],
bias: u32,
max_value: u32,
) -> Result<(IntSet<u32>, &[u8]), DecodingError> {
let Some((branch_factor, height)) = InputBitStream::<0>::decode_header(data) else {
return Err(DecodingError);
};
if height > branch_factor.max_height() {
return Err(DecodingError);
}
let result = match branch_factor {
BranchFactor::Two => {
Self::decode_sparse_bit_set_nodes::<2>(data, height, bias, max_value)
}
BranchFactor::Four => {
Self::decode_sparse_bit_set_nodes::<4>(data, height, bias, max_value)
}
BranchFactor::Eight => {
Self::decode_sparse_bit_set_nodes::<8>(data, height, bias, max_value)
}
BranchFactor::ThirtyTwo => {
Self::decode_sparse_bit_set_nodes::<32>(data, height, bias, max_value)
}
};
result.map(|(bitset, data)| (IntSet::<u32>::from_bitset(bitset), data))
}
fn decode_sparse_bit_set_nodes<const BF: u8>(
data: &[u8],
height: u8,
bias: u32,
max_value: u32,
) -> Result<(BitSet, &[u8]), DecodingError> {
let mut out = BitSet::empty();
if height == 0 {
return Ok((out, &data[1..]));
}
let mut builder = BitSetBuilder::start(&mut out);
let mut bits = InputBitStream::<BF>::from(data);
let mut queue = VecDeque::<NextNode>::new();
queue.push_back(NextNode { start: 0, depth: 1 });
'outer: while let Some(next) = queue.pop_front() {
let mut bits = bits.next().ok_or(DecodingError)?;
if bits == 0 {
let exp = (height as u32) - next.depth + 1;
let node_size = (BF as u64).pow(exp);
let Some(start) = u32::try_from(next.start)
.ok()
.and_then(|start| start.checked_add(bias))
.filter(|start| *start <= max_value)
else {
continue;
};
let end = u32::try_from(next.start + node_size - 1)
.unwrap_or(u32::MAX)
.saturating_add(bias)
.min(max_value);
builder.set.insert_range(start..=end);
continue;
}
let height = height as u32;
let exp = height - next.depth;
let next_node_size = (BF as u64).pow(exp);
loop {
let bit_index = bits.trailing_zeros();
if bit_index == 32 {
break;
}
if next.depth == height {
let Some(start) = u32::try_from(next.start)
.ok()
.and_then(|start| start.checked_add(bit_index))
.and_then(|start| start.checked_add(bias))
.filter(|start| *start <= max_value)
else {
break 'outer;
};
builder.insert(start);
} else {
let start_delta = bit_index as u64 * next_node_size;
queue.push_back(NextNode {
start: next.start + start_delta,
depth: next.depth + 1,
});
}
bits &= !(1 << bit_index); }
}
builder.finish();
if !bits.skip_nodes(queue.len() as u32) {
return Err(DecodingError);
}
Ok((out, &data[bits.bytes_consumed()..]))
}
pub fn to_sparse_bit_set(&self) -> Vec<u8> {
let mut candidates: Vec<Vec<u8>> = vec![];
let Some(max_value) = self.last() else {
return OutputBitStream::new(BranchFactor::Two, 0).into_bytes();
};
if BranchFactor::Two.tree_height_for(max_value) <= BranchFactor::Two.max_height() {
candidates.push(to_sparse_bit_set_with_bf::<2>(self));
}
if BranchFactor::Four.tree_height_for(max_value) <= BranchFactor::Four.max_height() {
candidates.push(to_sparse_bit_set_with_bf::<4>(self));
}
if BranchFactor::Eight.tree_height_for(max_value) <= BranchFactor::Eight.max_height() {
candidates.push(to_sparse_bit_set_with_bf::<8>(self));
}
if BranchFactor::ThirtyTwo.tree_height_for(max_value)
<= BranchFactor::ThirtyTwo.max_height()
{
candidates.push(to_sparse_bit_set_with_bf::<32>(self));
}
candidates.into_iter().min_by_key(|f| f.len()).unwrap()
}
}
pub fn to_sparse_bit_set_with_bf<const BF: u8>(set: &IntSet<u32>) -> Vec<u8> {
let branch_factor = BranchFactor::from_val(BF);
let Some(max_value) = set.last() else {
return OutputBitStream::new(branch_factor, 0).into_bytes();
};
let mut height = branch_factor.tree_height_for(max_value);
if height > branch_factor.max_height() {
if BF == 2 {
return to_sparse_bit_set_with_bf::<4>(set);
}
panic!("Height value exceeds the maximum for this branch factor.");
}
let mut os = OutputBitStream::new(branch_factor, height);
let mut nodes: Vec<Node> = vec![];
let mut indices = set.clone();
let mut filled_indices = IntSet::<u32>::all();
while height > 0 {
(indices, filled_indices) =
create_layer(branch_factor, indices, filled_indices, &mut nodes);
height -= 1;
}
for node in nodes.iter().rev() {
match node.node_type {
NodeType::Standard => os.write_node(node.bits),
NodeType::Filled => os.write_node(0),
NodeType::Skip => {}
};
}
os.into_bytes()
}
struct CreateLayerState<'a> {
upper_indices: IntSet<u32>,
upper_filled_indices: IntSet<u32>,
current_node: Option<Node>,
current_node_filled_bits: u32,
nodes: &'a mut Vec<Node>,
child_count: u64,
nodes_init_length: u64,
branch_factor: BranchFactor,
}
impl CreateLayerState<'_> {
fn commit_current_node(&mut self) {
let Some(mut node) = self.current_node.take() else {
return;
};
self.upper_indices.insert(node.parent_index);
if self.current_node_filled_bits == self.branch_factor.u32_mask() {
self.upper_filled_indices.insert(node.parent_index);
node.node_type = NodeType::Filled;
if self.nodes_init_length >= self.child_count {
let children_start_index = self.nodes_init_length.saturating_sub(self.child_count);
let children_end_index = self.nodes_init_length;
for child in
&mut self.nodes[children_start_index as usize..children_end_index as usize]
{
if child.parent_index >= node.parent_index * self.branch_factor.value()
&& child.parent_index < (node.parent_index + 1) * self.branch_factor.value()
{
child.node_type = NodeType::Skip;
}
}
}
}
self.nodes.push(node);
self.current_node_filled_bits = 0;
}
}
fn create_layer(
branch_factor: BranchFactor,
values: IntSet<u32>,
filled_values: IntSet<u32>,
nodes: &mut Vec<Node>,
) -> (IntSet<u32>, IntSet<u32>) {
let mut state = CreateLayerState {
upper_indices: IntSet::<u32>::empty(),
upper_filled_indices: IntSet::<u32>::empty(),
current_node: None,
current_node_filled_bits: 0,
child_count: values.len(),
nodes_init_length: nodes.len() as u64,
nodes,
branch_factor,
};
for v in values.iter().rev() {
let parent_index = v / branch_factor.value();
let prev_parent_index = state
.current_node
.as_ref()
.map_or(parent_index, |node| node.parent_index);
if prev_parent_index != parent_index {
state.commit_current_node();
}
let current_node = state.current_node.get_or_insert(Node {
bits: 0,
parent_index,
node_type: NodeType::Standard,
});
let mask = 0b1 << (v % branch_factor.value());
current_node.bits |= mask;
if filled_values.contains(v) {
state.current_node_filled_bits |= mask;
}
}
state.commit_current_node();
(state.upper_indices, state.upper_filled_indices)
}
enum NodeType {
Standard,
Filled,
Skip,
}
struct Node {
bits: u32,
parent_index: u32,
node_type: NodeType,
}
impl BranchFactor {
pub(crate) fn value(&self) -> u32 {
match self {
BranchFactor::Two => 2,
BranchFactor::Four => 4,
BranchFactor::Eight => 8,
BranchFactor::ThirtyTwo => 32,
}
}
pub(crate) fn max_height(&self) -> u8 {
match self {
BranchFactor::Two => 31,
BranchFactor::Four => 16,
BranchFactor::Eight => 11,
BranchFactor::ThirtyTwo => 7,
}
}
fn tree_height_for(&self, max_value: u32) -> u8 {
let mut height: u32 = 0;
let mut max_value = max_value;
loop {
height += 1;
max_value >>= self.node_size_log2();
if max_value == 0 {
break height as u8;
}
}
}
fn from_val(val: u8) -> BranchFactor {
match val {
2 => BranchFactor::Two,
4 => BranchFactor::Four,
8 => BranchFactor::Eight,
32 => BranchFactor::ThirtyTwo,
_ => panic!("Invalid branch factor."),
}
}
fn node_size_log2(&self) -> u32 {
match self {
BranchFactor::Two => 1,
BranchFactor::Four => 2,
BranchFactor::Eight => 3,
BranchFactor::ThirtyTwo => 5,
}
}
pub(crate) fn byte_mask(&self) -> u32 {
match self {
BranchFactor::Two => 0b00000011,
BranchFactor::Four => 0b00001111,
BranchFactor::Eight => 0b11111111,
BranchFactor::ThirtyTwo => 0b11111111,
}
}
fn u32_mask(&self) -> u32 {
match self {
BranchFactor::Two => 0b00000000_00000000_00000000_00000011,
BranchFactor::Four => 0b00000000_00000000_00000000_00001111,
BranchFactor::Eight => 0b00000000_00000000_00000000_11111111,
BranchFactor::ThirtyTwo => 0b11111111_11111111_11111111_11111111,
}
}
}
struct NextNode {
start: u64,
depth: u32,
}
#[cfg(test)]
#[allow(clippy::unusual_byte_groupings)]
mod test {
use super::*;
#[test]
fn spec_example_2() {
let bytes = [
0b00001110, 0b00100001, 0b00010001, 0b00000001, 0b00000100, 0b00000010, 0b00001000,
];
let set = IntSet::<u32>::from_sparse_bit_set(&bytes).unwrap();
let expected: IntSet<u32> = [2, 33, 323].iter().copied().collect();
assert_eq!(set, expected);
}
#[test]
fn spec_example_3() {
let bytes = [0b00000000];
let set = IntSet::<u32>::from_sparse_bit_set(&bytes).unwrap();
let expected: IntSet<u32> = [].iter().copied().collect();
assert_eq!(set, expected);
}
#[test]
fn spec_example_4() {
let bytes = [0b00001101, 0b00000011, 0b00110001];
let set = IntSet::<u32>::from_sparse_bit_set(&bytes).unwrap();
let mut expected: IntSet<u32> = IntSet::<u32>::empty();
expected.insert_range(0..=17);
assert_eq!(set, expected);
}
#[test]
fn invalid() {
let bytes = [
0b00001110, 0b00100001, 0b00010001, 0b00000001, 0b00000100, 0b00000010,
];
assert!(IntSet::<u32>::from_sparse_bit_set(&bytes).is_err());
let bytes = [
0b0_01000_11, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b00000001, 0b00000000,
0b00000000,
0b00000000,
0b10000000, ];
assert!(IntSet::<u32>::from_sparse_bit_set(&bytes).is_err());
}
#[test]
fn invalid_biased_and_bounded() {
let bytes = [0b0_00011_01, 0b0000_0011, 0b1111_0011];
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, u32::MAX).is_err());
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 20).is_err());
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 19).is_err());
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 18).is_err());
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 15).is_err());
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 14).is_err());
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 1, 20).is_err());
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 2, 20).is_err());
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 3, 20).is_err());
assert!(IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 6, 20).is_err());
}
#[test]
fn larger_than_u32() {
let bytes = [
0b0_00111_11, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b00000001, ];
assert_eq!(
IntSet::<u32>::from_sparse_bit_set(&bytes).unwrap(),
IntSet::<u32>::empty()
);
let bytes = [
0b0_00111_11, 0b00000000,
0b00000000,
0b00000000,
0b10000000, 0b00000000,
0b00000000,
0b00000000,
0b00000000, ];
assert_eq!(
IntSet::<u32>::from_sparse_bit_set(&bytes).unwrap(),
IntSet::<u32>::empty()
);
}
#[test]
fn from_sparse_bit_set_bounded_with_remaining_data() {
let bytes = [0b00001101, 0b00000011, 0b00110001, 0b10101010];
let mut expected: IntSet<u32> = IntSet::<u32>::empty();
expected.insert_range(0..=17);
assert_eq!(
IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 19).unwrap(),
(expected.clone(), &bytes[3..]),
);
}
#[test]
fn from_sparse_bit_set_biased_and_bounded() {
let bytes = [0b0_00011_01, 0b0000_0011, 0b1111_0011, 0b0000_0001];
let mut expected: IntSet<u32> = IntSet::<u32>::empty();
expected.insert_range(0..=20);
assert_eq!(
IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 20).unwrap(),
(expected.clone(), &bytes[4..])
);
let mut expected: IntSet<u32> = IntSet::<u32>::empty();
expected.insert_range(0..=19);
assert_eq!(
IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 19).unwrap(),
(expected.clone(), &bytes[4..])
);
let mut expected: IntSet<u32> = IntSet::<u32>::empty();
expected.insert_range(1..=20);
assert_eq!(
IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 1, 20).unwrap(),
(expected.clone(), &bytes[4..])
);
let mut expected: IntSet<u32> = IntSet::<u32>::empty();
expected.insert_range(1..=18);
assert_eq!(
IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 1, 18).unwrap(),
(expected.clone(), &bytes[4..])
);
let mut expected: IntSet<u32> = IntSet::<u32>::empty();
expected.insert_range(0..=14);
assert_eq!(
IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 14).unwrap(),
(expected.clone(), &bytes[4..])
);
let mut expected: IntSet<u32> = IntSet::<u32>::empty();
expected.insert_range(6..=20);
assert_eq!(
IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 6, 20).unwrap(),
(expected.clone(), &bytes[4..])
);
let mut expected: IntSet<u32> = IntSet::<u32>::empty();
expected.insert(0);
assert_eq!(
IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 0, 0).unwrap(),
(expected.clone(), &bytes[4..])
);
assert_eq!(
IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 1, 0).unwrap(),
(IntSet::<u32>::empty().clone(), &bytes[4..])
);
let bytes = [0b00000000];
let set = IntSet::<u32>::from_sparse_bit_set_bounded(&bytes, 5, 0)
.unwrap()
.0;
assert_eq!(set, IntSet::<u32>::empty());
}
#[test]
fn test_tree_height_for() {
assert_eq!(BranchFactor::Two.tree_height_for(0), 1);
assert_eq!(BranchFactor::Two.tree_height_for(1), 1);
assert_eq!(BranchFactor::Two.tree_height_for(2), 2);
assert_eq!(BranchFactor::Two.tree_height_for(117), 7);
assert_eq!(BranchFactor::Four.tree_height_for(0), 1);
assert_eq!(BranchFactor::Four.tree_height_for(3), 1);
assert_eq!(BranchFactor::Four.tree_height_for(4), 2);
assert_eq!(BranchFactor::Four.tree_height_for(63), 3);
assert_eq!(BranchFactor::Four.tree_height_for(64), 4);
assert_eq!(BranchFactor::Eight.tree_height_for(0), 1);
assert_eq!(BranchFactor::Eight.tree_height_for(7), 1);
assert_eq!(BranchFactor::Eight.tree_height_for(8), 2);
assert_eq!(BranchFactor::Eight.tree_height_for(32767), 5);
assert_eq!(BranchFactor::Eight.tree_height_for(32768), 6);
assert_eq!(BranchFactor::ThirtyTwo.tree_height_for(0), 1);
assert_eq!(BranchFactor::ThirtyTwo.tree_height_for(31), 1);
assert_eq!(BranchFactor::ThirtyTwo.tree_height_for(32), 2);
assert_eq!(BranchFactor::ThirtyTwo.tree_height_for(1_048_575), 4);
assert_eq!(BranchFactor::ThirtyTwo.tree_height_for(1_048_576), 5);
}
#[test]
fn generate_spec_example_2() {
let actual_bytes = to_sparse_bit_set_with_bf::<8>(&[2, 33, 323].iter().copied().collect());
let expected_bytes = [
0b00001110, 0b00100001, 0b00010001, 0b00000001, 0b00000100, 0b00000010, 0b00001000,
];
assert_eq!(actual_bytes, expected_bytes);
}
#[test]
fn generate_spec_example_3() {
let actual_bytes = to_sparse_bit_set_with_bf::<2>(&IntSet::<u32>::empty());
let expected_bytes = [0b00000000];
assert_eq!(actual_bytes, expected_bytes);
}
#[test]
fn generate_spec_example_4() {
let actual_bytes = to_sparse_bit_set_with_bf::<4>(&(0..=17).collect());
let expected_bytes = [0b00001101, 0b0000_0011, 0b0011_0001];
assert_eq!(actual_bytes, expected_bytes);
}
#[test]
fn encode_one_level() {
let actual_bytes = to_sparse_bit_set_with_bf::<8>(&[2, 6].iter().copied().collect());
let expected_bytes = [0b0_00001_10, 0b01000100];
assert_eq!(actual_bytes, expected_bytes);
}
#[test]
fn encode_one_level_filled() {
let actual_bytes = to_sparse_bit_set_with_bf::<8>(&(0..=7).collect());
let expected_bytes = [0b0_00001_10, 0b00000000];
assert_eq!(actual_bytes, expected_bytes);
}
#[test]
fn encode_two_level_filled() {
let actual_bytes = to_sparse_bit_set_with_bf::<8>(&(3..=21).collect());
let expected_bytes = [0b0_00010_10, 0b00000111, 0b11111000, 0b00000000, 0b00111111];
assert_eq!(actual_bytes, expected_bytes);
}
#[test]
fn encode_two_level_not_filled() {
let actual_bytes = to_sparse_bit_set_with_bf::<4>(&[0, 4, 8, 12].iter().copied().collect());
let expected_bytes = [0b0_00010_01, 0b0001_1111, 0b0001_0001, 0b0000_0001];
assert_eq!(actual_bytes, expected_bytes);
}
#[test]
fn encode_four_level_filled() {
let mut s = IntSet::<u32>::empty();
s.insert_range(64..=127); s.insert_range(512..=1023); s.insert(4000);
let actual_bytes = to_sparse_bit_set_with_bf::<8>(&s);
let expected_bytes = [
0b0_00100_10,
0b10000011,
0b00000010,
0b00000000,
0b01000000,
0b00000000,
0b00010000,
0b00000001,
];
assert_eq!(actual_bytes, expected_bytes);
}
#[test]
fn encode_bf32() {
let actual_bytes = to_sparse_bit_set_with_bf::<32>(&[2, 31, 323].iter().copied().collect());
let expected_bytes = [
0b0_00010_11,
0b00000001,
0b00000100,
0b00000000,
0b00000000,
0b00000100,
0b00000000,
0b00000000,
0b10000000,
0b00001000,
0b00000000,
0b00000000,
0b00000000,
];
assert_eq!(actual_bytes, expected_bytes);
}
#[test]
fn round_trip() {
let s1: IntSet<u32> = [11, 74, 9358].iter().copied().collect();
let mut s2: IntSet<u32> = s1.clone();
s2.insert_range(67..=412);
check_round_trip::<2>(&s1);
check_round_trip::<4>(&s1);
check_round_trip::<8>(&s1);
check_round_trip::<32>(&s1);
check_round_trip::<2>(&s2);
check_round_trip::<4>(&s2);
check_round_trip::<8>(&s2);
check_round_trip::<32>(&s2);
}
fn check_round_trip<const BF: u8>(s: &IntSet<u32>) {
let bytes = to_sparse_bit_set_with_bf::<BF>(s);
let s_prime = IntSet::<u32>::from_sparse_bit_set(&bytes).unwrap();
assert_eq!(*s, s_prime);
}
#[test]
fn find_smallest_bf() {
let s: IntSet<u32> = [11, 74, 9358].iter().copied().collect();
let bytes = s.to_sparse_bit_set();
assert_eq!(vec![0b0_00111_01], bytes[0..1]);
let s: IntSet<u32> = [
16, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
]
.iter()
.copied()
.collect();
let bytes = s.to_sparse_bit_set();
assert_eq!(vec![0b0_00001_11], bytes[0..1]);
}
#[test]
fn encode_maxu32() {
let s: IntSet<u32> = [1, u32::MAX].iter().copied().collect();
let bytes = s.to_sparse_bit_set();
let s_prime = IntSet::<u32>::from_sparse_bit_set(&bytes);
assert_eq!(s, s_prime.unwrap());
let s: IntSet<u32> = [1, u32::MAX].iter().copied().collect();
let bytes = to_sparse_bit_set_with_bf::<2>(&s);
let s_prime = IntSet::<u32>::from_sparse_bit_set(&bytes);
assert_eq!(s, s_prime.unwrap());
let s: IntSet<u32> = [1, u32::MAX].iter().copied().collect();
let bytes = to_sparse_bit_set_with_bf::<4>(&s);
let s_prime = IntSet::<u32>::from_sparse_bit_set(&bytes);
assert_eq!(s, s_prime.unwrap());
let s: IntSet<u32> = [1, u32::MAX].iter().copied().collect();
let bytes = to_sparse_bit_set_with_bf::<8>(&s);
let s_prime = IntSet::<u32>::from_sparse_bit_set(&bytes);
assert_eq!(s, s_prime.unwrap());
let s: IntSet<u32> = [1, u32::MAX].iter().copied().collect();
let bytes = to_sparse_bit_set_with_bf::<32>(&s);
let s_prime = IntSet::<u32>::from_sparse_bit_set(&bytes);
assert_eq!(s, s_prime.unwrap());
}
}