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
/// Models a sequence of characters in one or more forms as strings of equal length where each string represents one form
/// of characters in the sequence.
#[derive(Debug, PartialEq, Eq)]
pub struct CharacterSequence {
/// Character forms.
forms: Vec<String>,
}
impl CharacterSequence {
/// Creates a new instance from one or more sequences.
///
/// # Arguments
///
/// * `strings`: One or more characters strings, one for each form. At least one sequence MUST be defined. If
/// multiple sequences are defined, they MUST be of equal length.
pub fn new(strings: Vec<String>) -> Result<Self, String> {
if strings.is_empty() {
Err("At least one sequence must be defined".to_string())
} else if !strings.iter().all(|s| s.chars().count() == strings[0].chars().count()) {
Err("Strings have unequal length".to_string())
} else {
Ok(CharacterSequence { forms: strings })
}
}
/// Returns the array of strings that define character forms.
pub fn get_forms(&self) -> &Vec<String> {
&self.forms
}
/// Determines whether the character at the given index of the sequence matches the given value. Both original and
/// variant forms are considered.
///
/// # Arguments
///
/// * `index`: Character sequence index.
/// * `c`: Character to check for.
///
/// # Returns
///
/// True if sequence contains given character, false otherwise.
pub fn matches(&self, index: usize, c: char) -> bool {
self.forms.iter().any(|s| s.chars().nth(index).unwrap() == c)
}
/// Returns the length of character sequence.
pub fn length(&self) -> usize {
self.forms[0].chars().count()
}
}
#[cfg(test)]
mod tests {
use crate::rule::character_sequence::CharacterSequence;
#[test]
fn test_no_sequences_failure() {
let result = CharacterSequence::new(vec![]);
let expected_err = Err("At least one sequence must be defined".to_string());
assert_eq!(expected_err, result);
}
#[test]
fn test_unequal_sequence_failure() {
let result = CharacterSequence::new(vec!["12345".to_string(), "!@#$".to_string()]);
let expected_err = Err("Strings have unequal length".to_string());
assert_eq!(expected_err, result);
}
#[test]
fn test_matches() {
let sequence = CharacterSequence::new(vec![
"12345".to_string(),
"ABCDE".to_string(),
"abcde".to_string(),
])
.unwrap();
assert!(sequence.matches(0, '1'));
assert!(sequence.matches(0, 'A'));
assert!(sequence.matches(0, 'a'));
assert_eq!(false, sequence.matches(4, 'z'));
}
}