random.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use super::*; 17 18 impl<E: Environment> Distribution<StringType<E>> for Standard { 19 #[inline] 20 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> StringType<E> { 21 // Sample a random number up to 1/4th of the maximum bytes. 22 let num_bytes = rng.gen_range(1..(E::MAX_STRING_BYTES / 4) as usize); 23 // Sample a random string. 24 StringType::new(&rng.sample_iter(&Alphanumeric).take(num_bytes).map(char::from).collect::<String>()) 25 } 26 } 27 28 #[cfg(test)] 29 mod tests { 30 use super::*; 31 use alphavm_console_network_environment::Console; 32 33 use std::collections::HashMap; 34 35 type CurrentEnvironment = Console; 36 37 const ITERATIONS: usize = 100; 38 39 #[test] 40 fn test_random() { 41 // Initialize a map[string]=>occurrences to store all seen random elements. 42 let mut map = HashMap::with_capacity(ITERATIONS); 43 44 let mut rng = TestRng::default(); 45 46 for _ in 0..ITERATIONS { 47 // Sample a random value. 48 let string: StringType<CurrentEnvironment> = Uniform::rand(&mut rng); 49 50 // Add the new random value to the set. 51 map.entry(string).and_modify(|count| *count += 1).or_insert(1); 52 } 53 for (string, count) in map { 54 let allowed_occurrences = 1 + ITERATIONS / (string.len() * 10); 55 assert!(count <= allowed_occurrences, "Encountered an element with a count of {count}: {string}"); 56 } 57 } 58 }