use arbitrary::Arbitrary;
use anyhash::{Hasher, HasherWrite};
use ufotofu::codec_prelude::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Arbitrary)]
#[allow(missing_docs)]
pub enum TestDigest {
Clubs,
Diamonds,
Hearts,
Spades,
}
pub use TestDigest::*;
impl Encodable for TestDigest {
async fn encode<C>(&self, consumer: &mut C) -> Result<(), C::Error>
where
C: BulkConsumer<Item = u8> + ?Sized,
{
match self {
Clubs => consumer.consume_item(0).await,
Diamonds => consumer.consume_item(1).await,
Hearts => consumer.consume_item(2).await,
Spades => consumer.consume_item(3).await,
}
}
}
impl EncodableKnownLength for TestDigest {
fn len_of_encoding(&self) -> usize {
1
}
}
impl Decodable for TestDigest {
type ErrorReason = Blame;
async fn decode<P>(
producer: &mut P,
) -> Result<Self, DecodeError<P::Final, P::Error, Self::ErrorReason>>
where
P: BulkProducer<Item = u8> + ?Sized,
Self: Sized,
{
let byte = producer.produce_item().await?;
match byte {
0 => Ok(Clubs),
1 => Ok(Diamonds),
2 => Ok(Hearts),
3 => Ok(Spades),
_ => Err(DecodeError::Other(Blame::TheirFault)),
}
}
}
impl DecodableCanonic for TestDigest {
type ErrorCanonic = Blame;
async fn decode_canonic<P>(
producer: &mut P,
) -> Result<Self, DecodeError<P::Final, P::Error, Self::ErrorCanonic>>
where
P: BulkProducer<Item = u8> + ?Sized,
Self: Sized,
{
Self::decode(producer).await
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Arbitrary, Default)]
pub struct TestDigestHasher(u8);
impl HasherWrite for TestDigestHasher {
fn write(&mut self, bytes: &[u8]) {
for byte in bytes {
self.0 = self.0.wrapping_add(*byte)
}
}
}
impl Hasher<TestDigest> for TestDigestHasher {
fn finish(&self) -> TestDigest {
match self.0 % 4 {
0 => TestDigest::Clubs,
1 => TestDigest::Diamonds,
2 => TestDigest::Hearts,
3 => TestDigest::Spades,
_ => unreachable!(),
}
}
}