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
101
102
103
104
105
106
107
108
109
110
pub struct BitString {
s: String,
}
impl BitString {
pub fn new(s: &str) -> Self {
let parsed = s
.chars()
.filter(|c| match c {
'0' => true,
'1' => true,
'_' => false,
_ => panic!("`str` must consist of '0' or '1'. '{}' included.", c),
})
.collect::<String>();
assert!(!parsed.is_empty(), "`str` must contain any '0' or '1'.");
Self {
s: String::from(parsed),
}
}
pub fn str(&self) -> &str {
&self.s
}
}
#[cfg(test)]
mod new_success_tests {
use super::super::BitString;
macro_rules! parameterized_from_valid_str_tests {
($($name:ident: $value:expr,)*) => {
$(
#[test]
fn $name() {
let (in_s, expected_str) = $value;
let bvs = BitString::new(in_s);
assert_eq!(bvs.str(), expected_str);
}
)*
}
}
parameterized_from_valid_str_tests! {
s1: ("0", "0"),
s2: ("1", "1"),
s3: ("00", "00"),
s4: ("01", "01"),
s5: ("10", "10"),
s6: ("11", "11"),
s7_1: ("01010101010111001000001", "01010101010111001000001"),
s7_2: ("01010101_01011100_1000001", "01010101010111001000001"),
}
}
#[cfg(test)]
mod new_failure_tests {
use super::super::BitString;
macro_rules! parameterized_from_invalid_str_tests {
($($name:ident: $value:expr,)*) => {
$(
#[test]
#[should_panic]
fn $name() {
let in_s = $value;
let _ = BitString::new(in_s);
}
)*
}
}
parameterized_from_invalid_str_tests! {
s0: "",
s1: " ",
s2: " 0",
s3: "0 ",
s4: "1 0",
s5: "0",
s6: "1",
s7: "012",
s8: "01二",
s9: "_____",
}
}