diff --git a/node/libs/utils/src/encode.rs b/node/libs/utils/src/encode.rs new file mode 100644 index 00000000..8f691790 --- /dev/null +++ b/node/libs/utils/src/encode.rs @@ -0,0 +1,66 @@ +//! Utilites for testing encodings. +use rand::{ + distributions::{Alphanumeric, DistString, Distribution}, + Rng, +}; +use zksync_concurrency::net; + +/// Distribution for testing encodings. +pub struct EncodeDist { + /// Generate configs with only required fields. + pub required_only: bool, + /// Generate decimal fractions for f64 + /// to avoid rounding errors of decimal encodings. + pub decimal_fractions: bool, +} + +impl EncodeDist { + /// Returns a small non-empty range if `required_only` is false. + /// Returns an empty range otherwise. + pub fn sample_range(&self, rng: &mut (impl Rng + ?Sized)) -> std::ops::Range { + if self.required_only { + 0..0 + } else { + 0..rng.gen_range(5..10) + } + } +} + +impl Distribution for EncodeDist { + fn sample(&self, rng: &mut R) -> std::net::SocketAddr { + std::net::SocketAddr::new(std::net::IpAddr::from(rng.gen::<[u8; 16]>()), rng.gen()) + } +} + +impl Distribution for EncodeDist { + fn sample(&self, rng: &mut R) -> net::Host { + Distribution::::sample(self, rng).into() + } +} + +impl Distribution for EncodeDist { + fn sample(&self, rng: &mut R) -> String { + let n = self.sample_range(rng).len(); + Alphanumeric.sample_string(rng, n) + } +} + +impl Distribution> for EncodeDist +where + EncodeDist: Distribution, +{ + fn sample(&self, rng: &mut R) -> Option { + self.sample_range(rng).map(|_| self.sample(rng)).next() + } +} + +impl Distribution for EncodeDist { + fn sample(&self, rng: &mut R) -> f64 { + if self.decimal_fractions { + const PRECISION: usize = 1000000; + #[allow(clippy::float_arithmetic)] + return rng.gen_range(0..PRECISION) as f64 / PRECISION as f64; + } + rng.gen() + } +} diff --git a/node/libs/utils/src/lib.rs b/node/libs/utils/src/lib.rs index 7cff4361..71fc6af1 100644 --- a/node/libs/utils/src/lib.rs +++ b/node/libs/utils/src/lib.rs @@ -1,7 +1,7 @@ //! Crate that holds several small utilities and primitives. +mod encode; pub mod enum_util; pub mod pipe; -mod encode; pub use encode::*;