#[ derive(Debug, Clone, Copy) ]
pub enum DataSize
{
Small,
Medium,
Large,
Huge,
Custom(usize),
}
impl DataSize
{
#[ must_use ]
pub fn size( &self ) -> usize
{
match self
{
DataSize ::Small => 10,
DataSize ::Medium => 100,
DataSize ::Large => 1000,
DataSize ::Huge => 10000,
DataSize ::Custom(size) => *size,
}
}
#[ must_use ]
pub fn standard_sizes() -> Vec< DataSize >
{
vec![DataSize ::Small, DataSize ::Medium, DataSize ::Large, DataSize ::Huge]
}
}
#[ must_use ]
pub fn generate_list_data(size: DataSize) -> String
{
generate_list_data_with_delimiter(size, ",")
}
#[ must_use ]
pub fn generate_list_data_with_delimiter(size: DataSize, delimiter: &str) -> String
{
(1..=size.size())
.map(|i| format!("item{i}"))
.collect :: < Vec<_ >>()
.join(delimiter)
}
#[ must_use ]
pub fn generate_numeric_list(size: DataSize) -> String
{
(1..=size.size())
.map(|i| i.to_string())
.collect :: < Vec<_ >>()
.join(",")
}
#[ must_use ]
pub fn generate_map_data(size: DataSize) -> String
{
generate_map_data_with_delimiters(size, ",", "=")
}
#[ must_use ]
pub fn generate_map_data_with_delimiters(size: DataSize, entry_delimiter: &str, kv_delimiter: &str) -> String
{
(1..=size.size())
.map(|i| format!("key{i}{kv_delimiter}value{i}"))
.collect :: < Vec<_ >>()
.join(entry_delimiter)
}
#[ must_use ]
pub fn generate_enum_data(size: DataSize) -> String
{
(1..=size.size())
.map(|i| format!("choice{i}"))
.collect :: < Vec<_ >>()
.join(",")
}
#[ must_use ]
pub fn generate_string_data(length: usize) -> String
{
"a".repeat(length)
}
#[ must_use ]
pub fn generate_variable_strings(count: usize, min_len: usize, max_len: usize) -> Vec< String >
{
let mut strings = Vec ::with_capacity(count);
let step = if count > 1 { (max_len - min_len) / (count - 1) } else { 0 };
for i in 0..count
{
let len = min_len + (i * step);
strings.push("x".repeat(len));
}
strings
}
#[ must_use ]
pub fn generate_nested_data(depth: usize, width: usize) -> String
{
fn generate_level(current_depth: usize, max_depth: usize, width: usize) -> String
{
if current_depth >= max_depth
{
return format!("\"value{current_depth}\"");
}
let items: Vec< String > = (0..width)
.map(|i| {
let key = format!("key{i}");
let value = generate_level(current_depth + 1, max_depth, width);
format!("\"{key}\" : {value}")
})
.collect();
format!("{{{}}}", items.join(", "))
}
generate_level(0, depth, width)
}
#[ must_use ]
pub fn generate_file_paths(size: DataSize) -> Vec< String >
{
(1..=size.size())
.map(|i| format!("/path/to/file{i}.txt"))
.collect()
}
#[ must_use ]
pub fn generate_urls(size: DataSize) -> Vec< String >
{
(1..=size.size())
.map(|i| format!("https: //example{i}.com/path"))
.collect()
}
#[ derive(Debug) ]
pub struct SeededGenerator
{
seed: u64,
}
impl SeededGenerator
{
#[ must_use ]
pub fn new(seed: u64) -> Self
{
Self { seed }
}
fn next( &mut self ) -> u64
{
self.seed = self.seed.wrapping_mul(1_103_515_245).wrapping_add(12345);
self.seed
}
pub fn random_string(&mut self, length: usize) -> String
{
const CHARS: &[ u8] = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
(0..length)
.map(|_| {
#[ allow(clippy ::cast_possible_truncation) ]
let idx = (self.next() as usize) % CHARS.len();
CHARS[idx] as char
})
.collect()
}
pub fn random_int(&mut self, min: i32, max: i32) -> i32
{
#[ allow(clippy ::cast_sign_loss) ]
let range = (max - min) as u64;
#[ allow(clippy ::cast_possible_truncation) ]
let result = (self.next() % range) as i32;
min + result
}
pub fn random_vec(&mut self, size: usize, min: i32, max: i32) -> Vec< i32 >
{
(0..size)
.map(|_| self.random_int(min, max))
.collect()
}
}
#[ must_use ]
pub fn generate_random_vec(size: usize) -> Vec< i32 >
{
let mut gen = SeededGenerator ::new(42);
gen.random_vec(size, 1, 1000)
}
#[ derive(Debug) ]
pub struct ParsingTestData;
impl ParsingTestData
{
#[ must_use ]
pub fn command_args(size: DataSize) -> String
{
(1..=size.size())
.map(|i| format!("--arg{i} value{i}"))
.collect :: < Vec<_ >>()
.join(" ")
}
#[ must_use ]
pub fn config_pairs(size: DataSize) -> String
{
(1..=size.size())
.map(|i| format!("setting{i}=value{i}"))
.collect :: < Vec<_ >>()
.join("\n")
}
#[ must_use ]
pub fn csv_data(rows: usize, cols: usize) -> String
{
let header = (1..=cols)
.map(|i| format!("column{i}"))
.collect :: < Vec<_ >>()
.join(",");
let mut lines = vec![header];
for row in 1..=rows
{
let line = (1..=cols)
.map(|col| format!("row{row}col{col}"))
.collect :: < Vec<_ >>()
.join(",");
lines.push(line);
}
lines.join("\n")
}
#[ must_use ]
pub fn json_objects(size: DataSize) -> String
{
let objects: Vec< String > = (1..=size.size())
.map(|i| format!(r#"{{"id" : {}, "name" : "object{}", "value" : {}}}"#, i, i, i * 10))
.collect();
format!("[{}]", objects.join(", "))
}
}