use super::*;
impl<N: Network> FromBits for Plaintext<N> {
fn from_bits_le(bits_le: &[bool]) -> Result<Self> {
let bits = bits_le;
let mut index = 0;
let mut next_bits = |n: usize| -> Result<&[bool]> {
let subslice = bits.get(index..index + n);
if let Some(next_bits) = subslice {
index += n;
Ok(next_bits)
} else {
bail!("Insufficient bits");
}
};
let variant = next_bits(2)?;
let variant = [variant[0], variant[1]];
if variant == [false, false] {
let literal_variant = u8::from_bits_le(next_bits(8)?)?;
let literal_size = u16::from_bits_le(next_bits(16)?)?;
let literal = Literal::from_bits_le(literal_variant, next_bits(literal_size as usize)?)?;
Ok(Self::Literal(literal, OnceCell::with_value(bits_le.to_vec())))
}
else if variant == [false, true] {
let num_members = u8::from_bits_le(next_bits(8)?)?;
if num_members as usize > N::MAX_STRUCT_ENTRIES {
bail!("Struct exceeds maximum of entries.");
}
let mut members = IndexMap::with_capacity(num_members as usize);
for _ in 0..num_members {
let identifier_size = u8::from_bits_le(next_bits(8)?)?;
let identifier = Identifier::from_bits_le(next_bits(identifier_size as usize)?)?;
let member_size = u16::from_bits_le(next_bits(16)?)?;
let value = Plaintext::from_bits_le(next_bits(member_size as usize)?)?;
if members.insert(identifier, value).is_some() {
bail!("Duplicate identifier in struct.");
}
}
Ok(Self::Struct(members, OnceCell::with_value(bits_le.to_vec())))
}
else if variant == [true, false] {
let num_elements = u32::from_bits_le(next_bits(32)?)?;
if num_elements as usize > N::MAX_ARRAY_ELEMENTS {
bail!("Array exceeds maximum of elements.");
}
let mut elements = Vec::with_capacity(num_elements as usize);
for _ in 0..num_elements {
let element_size = u16::from_bits_le(next_bits(16)?)?;
let element = Plaintext::from_bits_le(next_bits(element_size as usize)?)?;
elements.push(element);
}
Ok(Self::Array(elements, OnceCell::with_value(bits_le.to_vec())))
}
else {
bail!("Unknown plaintext variant - {variant:?}");
}
}
fn from_bits_be(bits_be: &[bool]) -> Result<Self> {
let bits = bits_be;
let mut index = 0;
let mut next_bits = |n: usize| -> Result<&[bool]> {
let subslice = bits.get(index..index + n);
if let Some(next_bits) = subslice {
index += n;
Ok(next_bits)
} else {
bail!("Insufficient bits");
}
};
let variant = next_bits(2)?;
let variant = [variant[0], variant[1]];
if variant == [false, false] {
let literal_variant = u8::from_bits_be(next_bits(8)?)?;
let literal_size = u16::from_bits_be(next_bits(16)?)?;
let literal = Literal::from_bits_be(literal_variant, next_bits(literal_size as usize)?)?;
Ok(Self::Literal(literal, OnceCell::with_value(bits_be.to_vec())))
}
else if variant == [false, true] {
let num_members = u8::from_bits_be(next_bits(8)?)?;
if num_members as usize > N::MAX_STRUCT_ENTRIES {
bail!("Struct exceeds maximum of entries.");
}
let mut members = IndexMap::with_capacity(num_members as usize);
for _ in 0..num_members {
let identifier_size = u8::from_bits_be(next_bits(8)?)?;
let identifier = Identifier::from_bits_be(next_bits(identifier_size as usize)?)?;
let member_size = u16::from_bits_be(next_bits(16)?)?;
let value = Plaintext::from_bits_be(next_bits(member_size as usize)?)?;
if members.insert(identifier, value).is_some() {
bail!("Duplicate identifier in struct.");
}
}
Ok(Self::Struct(members, OnceCell::with_value(bits_be.to_vec())))
}
else if variant == [true, false] {
let num_elements = u32::from_bits_be(next_bits(32)?)?;
if num_elements as usize > N::MAX_ARRAY_ELEMENTS {
bail!("Array exceeds maximum of elements.");
}
let mut elements = Vec::with_capacity(num_elements as usize);
for _ in 0..num_elements {
let element_size = u16::from_bits_be(next_bits(16)?)?;
let element = Plaintext::from_bits_be(next_bits(element_size as usize)?)?;
elements.push(element);
}
Ok(Self::Array(elements, OnceCell::with_value(bits_be.to_vec())))
}
else {
bail!("Unknown plaintext variant - {variant:?}");
}
}
}