use syncify::syncify;
use syncify::syncify_replace;
pub const fn max_power(max_size: usize) -> u8 {
if max_size < 256 {
1
} else if max_size < 65536 {
2
} else if max_size < 16777216 {
3
} else if max_size < 4294967296 {
4
} else if max_size < (256_usize).pow(5) {
5
} else if max_size < (256_usize).pow(6) {
6
} else if max_size < (256_usize).pow(7) {
7
} else {
8
}
}
#[syncify(encoding_sync)]
pub(super) mod encoding {
use super::*;
use core::mem::size_of;
use crate::error::DecodeError;
#[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)]
use ufotofu::local_nb::{BulkConsumer, BulkProducer};
pub async fn encode_max_power<C>(
value: usize,
max_size: usize,
consumer: &mut C,
) -> Result<(), C::Error>
where
C: BulkConsumer<Item = u8>,
{
if value > max_size {
panic!("Can't encode a value larger than its maximum possible value!")
}
let power = max_power(max_size);
let value_encoded_raw: [u8; size_of::<u64>()] = value.to_be_bytes();
consumer
.bulk_consume_full_slice(&value_encoded_raw[size_of::<u64>() - (power as usize)..])
.await
.map_err(|f| f.reason)?;
Ok(())
}
pub async fn decode_max_power<P>(
max_size: usize,
producer: &mut P,
) -> Result<u64, DecodeError<P::Error>>
where
P: BulkProducer<Item = u8>,
{
let power = max_power(max_size);
let mut slice = [0u8; size_of::<u64>()];
producer
.bulk_overwrite_full_slice(&mut slice[size_of::<u64>() - (power as usize)..])
.await?;
Ok(u64::from_be_bytes(slice))
}
}
pub use encoding::{decode_max_power, encode_max_power};