1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use rand::{Rng, thread_rng};
const STR_SOURCE: &[&str] = &["kettle", "compare", "two", "pump", "sofa", "grateful", "thank", "tame", "warlike", "cute", "cooing", "overflow", "tail", "juice", "downtown", "modern", "agree", "dress", "memorise", "pass", "blow", "knowing", "crush", "slippery", "fasten", "faded", "various", "consider", "drawer", "explain", "burn", "smile", "found", "filthy", "wink", "pleasure", "jog", "flashy", "trip", "vegetable"];
enum CellType {
/// Supported Types for column-cells
Float,
Str,
Int
}
struct Cell {
/// Represents one cell in a row
cell_value: String
}
pub struct CsvLine {
/// Represents one row of csv consisting of multiple Cells with CellTypes
pub line_value: String
}
impl Cell {
/// Populate cell according to given CellType
/// ```
/// use csvgen::generator::{Cell,CellType};
/// let c_type = CellType::Int;
/// let c = Cell::new(c_type);
/// ```
pub fn new(c_type: CellType) -> Cell {
Cell {
cell_value: match c_type {
CellType::Float => {
// TODO: allow user-provided range parameters
let r_val: f64 = thread_rng().gen_range(-429.842,765.123);
String::from(format!("{}", r_val))
},
CellType::Str => {
// TODO: rework "string" with user-provided selection of
// value-categories like names, email, addresses etc
let mut rng = thread_rng();
let mut r_val: Vec<&str> = Vec::new();
for _s in 0..rng.gen_range(1,5) {
r_val.push(rng.choose(&STR_SOURCE).unwrap());
}
String::from(format!("\"{}\"",r_val.join(" ")))
},
CellType::Int => {
// TODO: allow user-provided range parameters
let r_val: isize = thread_rng().gen_range(-2e6,2e6) as isize;
String::from(format!("{}",r_val))
},
}
}
}
}
impl CsvLine {
/// Create a csv-row according to given types.
/// For each type, a Cell will be generated. The Cell-value
/// is then pushed onto a String held by CsvLine.
/// ```
/// use csvgen::generator::CsvLine;
/// let line_types = Vec::from(vec!["int","string"]);
/// let line = CsvLine::new(&line_types);
/// ```
pub fn new(l_types: &Vec<String>) -> CsvLine {
let mut val: String = String::new();
for (cell_num, lt) in l_types.iter().enumerate() {
let t: CellType = match lt.as_ref() {
"string" => CellType::Str,
"int" => CellType::Int,
"float" => CellType::Float,
_ => panic!("Failed to determine cell type.")
};
let c = Cell::new(t);
val.push_str(&c.cell_value);
if cell_num < l_types.len()-1 {
val.push_str(",")
} else {
val.push_str("\n")
}
}
CsvLine {
line_value: val
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_csv_line_generation() {
use generator::CsvLine;
let test_types = Vec::from(vec!["string".to_owned(),"int".to_owned(),"float".to_owned()]);
let test_line = CsvLine::new(&test_types);
// TODO: make these tests more fancy
assert!(test_line.line_value.len() != 0);
}
}