use super::*;
impl<N: Network> FromBits for FinalizeOperation<N> {
fn from_bits_le(bits: &[bool]) -> Result<Self> {
let mut bits = bits.iter().cloned();
let mut next_bits = |n: usize| -> Result<Vec<bool>> {
let bits: Vec<_> = bits.by_ref().take(n).collect();
if bits.len() < n {
bail!("Insufficient bits");
}
Ok(bits)
};
let variant = u8::from_bits_le(&next_bits(8)?)?;
match variant {
0 => {
let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::InitializeMapping(mapping_id))
}
1 => {
let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
let key_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
let value_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::InsertKeyValue(mapping_id, key_id, value_id))
}
2 => {
let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
let key_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
let value_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id))
}
3 => {
let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
let key_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::RemoveKeyValue(mapping_id, key_id))
}
4 => {
let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::ReplaceMapping(mapping_id))
}
5 => {
let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::RemoveMapping(mapping_id))
}
6.. => bail!("Invalid finalize operation variant '{variant}'"),
}
}
fn from_bits_be(bits: &[bool]) -> Result<Self> {
let mut bits = bits.iter().cloned();
let mut next_bits = |n: usize| -> Result<Vec<bool>> {
let bits: Vec<_> = bits.by_ref().take(n).collect();
if bits.len() < n {
bail!("Insufficient bits");
}
Ok(bits)
};
let variant = u8::from_bits_be(&next_bits(8)?)?;
match variant {
0 => {
let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::InitializeMapping(mapping_id))
}
1 => {
let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
let key_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
let value_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::InsertKeyValue(mapping_id, key_id, value_id))
}
2 => {
let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
let key_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
let value_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id))
}
3 => {
let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
let key_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::RemoveKeyValue(mapping_id, key_id))
}
4 => {
let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::ReplaceMapping(mapping_id))
}
5 => {
let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
Ok(Self::RemoveMapping(mapping_id))
}
6.. => bail!("Invalid finalize operation variant '{variant}'"),
}
}
}
impl<N: Network> ToBits for FinalizeOperation<N> {
fn write_bits_le(&self, vec: &mut Vec<bool>) {
match self {
Self::InitializeMapping(mapping_id) => {
0u8.write_bits_le(vec);
mapping_id.write_bits_le(vec);
}
Self::InsertKeyValue(mapping_id, key_id, value_id) => {
1u8.write_bits_le(vec);
mapping_id.write_bits_le(vec);
key_id.write_bits_le(vec);
value_id.write_bits_le(vec);
}
Self::UpdateKeyValue(mapping_id, key_id, value_id) => {
2u8.write_bits_le(vec);
mapping_id.write_bits_le(vec);
key_id.write_bits_le(vec);
value_id.write_bits_le(vec);
}
Self::RemoveKeyValue(mapping_id, key_id) => {
3u8.write_bits_le(vec);
mapping_id.write_bits_le(vec);
key_id.write_bits_le(vec);
}
Self::ReplaceMapping(mapping_id) => {
4u8.write_bits_le(vec);
mapping_id.write_bits_le(vec);
}
Self::RemoveMapping(mapping_id) => {
5u8.write_bits_le(vec);
mapping_id.write_bits_le(vec);
}
}
}
fn write_bits_be(&self, vec: &mut Vec<bool>) {
match self {
Self::InitializeMapping(mapping_id) => {
0u8.write_bits_be(vec);
mapping_id.write_bits_be(vec);
}
Self::InsertKeyValue(mapping_id, key_id, value_id) => {
1u8.write_bits_be(vec);
mapping_id.write_bits_be(vec);
key_id.write_bits_be(vec);
value_id.write_bits_be(vec);
}
Self::UpdateKeyValue(mapping_id, key_id, value_id) => {
2u8.write_bits_be(vec);
mapping_id.write_bits_be(vec);
key_id.write_bits_be(vec);
value_id.write_bits_be(vec);
}
Self::RemoveKeyValue(mapping_id, key_id) => {
3u8.write_bits_be(vec);
mapping_id.write_bits_be(vec);
key_id.write_bits_be(vec);
}
Self::ReplaceMapping(mapping_id) => {
4u8.write_bits_be(vec);
mapping_id.write_bits_be(vec);
}
Self::RemoveMapping(mapping_id) => {
5u8.write_bits_be(vec);
mapping_id.write_bits_be(vec);
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bits_le() {
for expected in crate::logic::finalize_operation::test_helpers::sample_finalize_operations() {
let expected_bits = expected.to_bits_le();
assert_eq!(expected, FinalizeOperation::from_bits_le(&expected_bits[..]).unwrap());
}
}
#[test]
fn test_bits_be() {
for expected in crate::logic::finalize_operation::test_helpers::sample_finalize_operations() {
let expected_bits = expected.to_bits_be();
assert_eq!(expected, FinalizeOperation::from_bits_be(&expected_bits[..]).unwrap());
}
}
}