use crate::scheme::EntropyScheme;
use crate::sink::AsSink;
use crate::sink::Sink;
use crate::source::AsSource;
use crate::source::Source;
use crate::EntropicError;
#[cfg(feature = "alloc")]
use alloc::borrow::{Cow, ToOwned};
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::collections::{BTreeMap, LinkedList, VecDeque};
#[cfg(feature = "alloc")]
use alloc::ffi::CString;
#[cfg(feature = "alloc")]
use alloc::rc::Rc;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "alloc")]
use alloc::sync::Arc;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::array;
use core::cell::{Cell, RefCell};
use core::marker::PhantomData;
#[cfg(feature = "bitvec")]
use core::mem;
use core::net::IpAddr;
use core::net::Ipv4Addr;
use core::net::Ipv6Addr;
use std::collections::BTreeSet;
#[cfg(feature = "std")]
use std::sync::{
atomic::{AtomicBool, Ordering},
Mutex,
};
#[cfg(feature = "bitvec")]
use bitvec::prelude::*;
#[cfg(all(feature = "alloc", feature = "tinyvec"))]
use tinyvec::{Array, ArrayVec, TinyVec};
struct CountIter<T, I: Iterator<Item = T>> {
iter: I,
num_iterations: usize,
}
#[allow(dead_code)]
impl<T, I: Iterator<Item = T>> CountIter<T, I> {
#[inline]
pub fn new(iter: I) -> Self {
Self {
iter,
num_iterations: 0,
}
}
#[inline]
pub fn num_iterations(&self) -> usize {
self.num_iterations
}
}
impl<T, I: Iterator<Item = T>> Iterator for CountIter<T, I> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
Some(t) => {
self.num_iterations = self.num_iterations.saturating_add(1);
Some(t)
}
None => None,
}
}
}
impl<T, I: Iterator<Item = T>> Clone for CountIter<T, I>
where
I: Clone,
{
#[inline]
fn clone(&self) -> Self {
Self {
iter: self.iter.clone(),
num_iterations: self.num_iterations,
}
}
}
pub trait Entropic: Sized {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError>;
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError>;
#[inline]
fn from_entropy<'a, S: AsSource<'a>, E: EntropyScheme>(
source: S,
) -> Result<Self, EntropicError> {
let mut s = source.to_source::<E>();
Self::from_entropy_source(&mut s)
}
#[inline]
fn to_entropy<'a, S: AsSink<'a>, E: EntropyScheme>(
&self,
destination: S,
) -> Result<usize, EntropicError> {
let mut s = destination.to_sink::<E>();
self.to_entropy_sink(&mut s)
}
}
#[cfg(feature = "std")]
impl<T: Entropic> Entropic for Mutex<T> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
Ok(Mutex::new(T::from_entropy_source(source)?))
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
self.lock()
.map_err(|_| EntropicError::PoisonedLock)?
.to_entropy_sink(sink)
}
}
#[cfg(feature = "alloc")]
impl<'b, T> Entropic for Cow<'b, T>
where
T: ToOwned + Entropic + ?Sized,
<T as ToOwned>::Owned: Entropic,
{
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
T::Owned::from_entropy_source(source).map(Cow::Owned)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
self.as_ref().to_entropy_sink(sink)
}
}
impl<T> Entropic for PhantomData<T> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
_source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
Ok(PhantomData)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
_sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
Ok(0)
}
}
#[cfg(feature = "alloc")]
impl<T: Entropic> Entropic for Rc<T> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
T::from_entropy_source(source).map(Rc::new)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
self.as_ref().to_entropy_sink(sink)
}
}
#[cfg(feature = "alloc")]
impl<T: Entropic> Entropic for Arc<T> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
T::from_entropy_source(source).map(Arc::new)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
self.as_ref().to_entropy_sink(sink)
}
}
impl<T: Entropic + Copy> Entropic for Cell<T> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
T::from_entropy_source(source).map(Cell::new)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
self.get().to_entropy_sink(sink)
}
}
#[cfg(feature = "alloc")]
impl<T: Entropic> Entropic for Box<T> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
T::from_entropy_source(source).map(Box::new)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
self.as_ref().to_entropy_sink(sink)
}
}
impl<T: Entropic> Entropic for RefCell<T> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
T::from_entropy_source(source).map(RefCell::new)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
self.borrow().to_entropy_sink(sink)
}
}
#[cfg(feature = "std")]
impl Entropic for AtomicBool {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
source.get_bool().map(AtomicBool::new)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
sink.put_bool(self.load(Ordering::Relaxed)) }
}
#[cfg(feature = "alloc")]
impl<T: Entropic, const N: usize> Entropic for [T; N] {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let results_arr: [Result<T, EntropicError>; N] =
array::from_fn(|_| T::from_entropy_source(source));
results_arr
.into_iter()
.collect::<Result<Vec<T>, EntropicError>>()?
.try_into()
.map_err(|_| EntropicError::Internal)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = 0usize;
for arr_value in self {
written = written
.checked_add(arr_value.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
Ok(written)
}
}
impl Entropic for bool {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
source.get_bool()
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
sink.put_bool(*self)
}
}
impl Entropic for char {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
source.get_char()
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
sink.put_char(*self)
}
}
#[cfg(feature = "alloc")]
impl Entropic for String {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
source.get_string()
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
sink.put_string(self)
}
}
#[cfg(feature = "alloc")]
impl Entropic for Box<str> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
source.get_string().map(Box::<str>::from)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
sink.put_string(self)
}
}
#[cfg(feature = "alloc")]
impl Entropic for CString {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
source.get_cstring()
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
sink.put_cstring(self)
}
}
impl Entropic for () {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
_source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
Ok(())
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
_sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
Ok(0)
}
}
impl<A> Entropic for (A,)
where
A: Entropic
{
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
Ok((A::from_entropy_source(source)?,))
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
Ok(self.0.to_entropy_sink(sink)?)
}
}
impl<A, B> Entropic for (A, B)
where
A: Entropic,
B: Entropic
{
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
Ok((A::from_entropy_source(source)?, B::from_entropy_source(source)?))
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
Ok(self.0.to_entropy_sink(sink)? + self.1.to_entropy_sink(sink)?)
}
}
impl<A, B, C> Entropic for (A, B, C)
where
A: Entropic,
B: Entropic,
C: Entropic
{
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
Ok((A::from_entropy_source(source)?, B::from_entropy_source(source)?, C::from_entropy_source(source)?))
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
Ok(self.0.to_entropy_sink(sink)? + self.1.to_entropy_sink(sink)? + self.2.to_entropy_sink(sink)?)
}
}
impl<A, B, C, D> Entropic for (A, B, C, D)
where
A: Entropic,
B: Entropic,
C: Entropic,
D: Entropic
{
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
Ok((A::from_entropy_source(source)?, B::from_entropy_source(source)?, C::from_entropy_source(source)?, D::from_entropy_source(source)?))
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
Ok(self.0.to_entropy_sink(sink)? + self.1.to_entropy_sink(sink)? + self.2.to_entropy_sink(sink)? + self.3.to_entropy_sink(sink)?)
}
}
impl<A: Entropic, B: Entropic> Entropic for Result<A, B> {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let is_ok = source.get_optional()?;
if is_ok {
Ok(Ok(A::from_entropy_source(source)?))
} else {
Ok(Err(B::from_entropy_source(source)?))
}
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written;
match self {
Ok(a) => {
written = sink.put_optional(true)?;
written = written
.checked_add(a.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
Err(b) => {
written = sink.put_optional(false)?;
written = written
.checked_add(b.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
}
Ok(written)
}
}
impl<T: Entropic> Entropic for Option<T> {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let is_some = source.get_optional()?;
if is_some {
Ok(Some(T::from_entropy_source(source)?))
} else {
Ok(None)
}
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written;
match self {
Some(t) => {
written = sink.put_optional(true)?;
written = written
.checked_add(t.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
None => written = sink.put_optional(false)?,
}
Ok(written)
}
}
impl<T: Entropic> Entropic for Vec<T> {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let len = source.get_unbounded_len()?;
let mut v = Vec::with_capacity(len);
for _ in 0..len {
v.push(T::from_entropy_source(source)?);
}
Ok(v)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = sink.put_unbounded_len(self.len())?;
for val in self.iter() {
written = written
.checked_add(val.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
Ok(written)
}
}
impl<T: Entropic> Entropic for Box<[T]> {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let v = Vec::from_entropy_source(source)?;
Ok(v.into_boxed_slice())
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = sink.put_unbounded_len(self.len())?;
for val in self.iter() {
written = written
.checked_add(val.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
Ok(written)
}
}
impl<K: Entropic + Ord, V: Entropic> Entropic for BTreeMap<K, V> {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let len = source.get_unbounded_len()?;
let mut m = BTreeMap::new();
for _ in 0..len {
m.insert(K::from_entropy_source(source)?, V::from_entropy_source(source)?);
}
Ok(m)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = sink.put_unbounded_len(self.len())?;
for (k, v) in self.iter() {
written = written
.checked_add(k.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?
.checked_add(v.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
Ok(written)
}
}
impl<K: Entropic + Ord> Entropic for BTreeSet<K> {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let len = source.get_unbounded_len()?;
let mut s = BTreeSet::new();
for _ in 0..len {
s.insert(K::from_entropy_source(source)?);
}
Ok(s)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = sink.put_unbounded_len(self.len())?;
for s in self.iter() {
written = written
.checked_add(s.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?
}
Ok(written)
}
}
impl<T: Entropic> Entropic for VecDeque<T> {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let len = source.get_unbounded_len()?;
let mut v = VecDeque::with_capacity(len);
for _ in 0..len {
v.push_back(T::from_entropy_source(source)?);
}
Ok(v)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = sink.put_unbounded_len(self.len())?;
for val in self.iter() {
written = written
.checked_add(val.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
Ok(written)
}
}
impl<T: Entropic> Entropic for LinkedList<T> {
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let len = source.get_unbounded_len()?;
let mut v = LinkedList::new();
for _ in 0..len {
v.push_back(T::from_entropy_source(source)?);
}
Ok(v)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = sink.put_unbounded_len(self.len())?;
for val in self.iter() {
written = written
.checked_add(val.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
Ok(written)
}
}
macro_rules! impl_entropic_int {
( $( $ty:ty),* ) => {
$(
impl Entropic for $ty {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item=&'a u8>, E: EntropyScheme>(source: &mut Source<'a, I, E>) -> Result<Self, EntropicError> {
Ok(<$ty>::from_le_bytes(source.get_bytearray()?))
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item=&'a mut u8>, E: EntropyScheme>(&self, sink: &mut Sink<'a, I, E>) -> Result<usize, EntropicError> {
sink.put_bytearray(self.to_le_bytes())
}
}
)*
}
}
impl_entropic_int!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64);
impl Entropic for Ipv4Addr {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
Ok(Ipv4Addr::from(u32::from_entropy_source(source)?))
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
u32::from(*self).to_entropy_sink(sink)
}
}
impl Entropic for Ipv6Addr {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
Ok(Ipv6Addr::from(<[u8; 16]>::from_entropy_source(source)?))
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
self.octets().to_entropy_sink(sink)
}
}
impl Entropic for IpAddr {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
if source.get_bool()? {
Ok(IpAddr::V6(Ipv6Addr::from_entropy_source(source)?))
} else {
Ok(IpAddr::V4(Ipv4Addr::from_entropy_source(source)?))
}
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = self.is_ipv6().to_entropy_sink(sink)?;
written += match self {
Self::V4(v4) => v4.to_entropy_sink(sink)?,
Self::V6(v6) => v6.to_entropy_sink(sink)?,
};
Ok(written)
}
}
#[cfg(feature = "bitvec")]
#[cfg(feature = "alloc")]
impl<T: BitStore + Entropic, U: BitOrder> Entropic for BitVec<T, U> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let len = source.get_unbounded_len()?;
let store_len = len / (8 * mem::size_of::<T>());
let bit_len = len % (8 * mem::size_of::<T>());
let mut bv_container = Vec::with_capacity(store_len.saturating_add(1));
for _ in 0..store_len {
bv_container.push(T::from_entropy_source(source)?);
}
let mut bv: BitVec<T, U> = BitVec::from_vec(bv_container);
for _ in 0..bit_len {
bv.push(bool::from_entropy_source(source)?);
}
Ok(bv)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = sink.put_unbounded_len(self.len())?;
let bit_len = self.len() % (8 * mem::size_of::<T>());
match self.as_raw_slice().split_last() {
None => Ok(written), Some((last, remainder)) => {
for value in remainder {
written = written
.checked_add(value.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
for bit in last.view_bits::<U>().iter().take(bit_len) {
written = written
.checked_add(bit.to_entropy_sink(sink)?)
.ok_or(EntropicError::Internal)?;
}
Ok(written)
}
}
}
}
#[cfg(feature = "tinyvec")]
impl<T: Entropic, A: Array<Item = T>> Entropic for ArrayVec<A> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let len = source.get_unbounded_len()?;
let mut arr = ArrayVec::new();
for _ in 0..len {
arr.push(T::from_entropy_source(source)?);
}
Ok(arr)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = sink.put_unbounded_len(self.len())?;
for elem in self.iter() {
written += elem.to_entropy_sink(sink)?;
}
Ok(written)
}
}
#[cfg(feature = "tinyvec")]
impl<T: Entropic, A: Array<Item = T>> Entropic for TinyVec<A> {
#[inline]
fn from_entropy_source<'a, I: Iterator<Item = &'a u8>, E: EntropyScheme>(
source: &mut Source<'a, I, E>,
) -> Result<Self, EntropicError> {
let len = source.get_unbounded_len()?;
let mut arr = TinyVec::new();
for _ in 0..len {
arr.push(T::from_entropy_source(source)?);
}
Ok(arr)
}
#[inline]
fn to_entropy_sink<'a, I: Iterator<Item = &'a mut u8>, E: EntropyScheme>(
&self,
sink: &mut Sink<'a, I, E>,
) -> Result<usize, EntropicError> {
let mut written = sink.put_unbounded_len(self.len())?;
for elem in self.iter() {
written += elem.to_entropy_sink(sink)?;
}
Ok(written)
}
}