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
use properties::{Length, Angle, Transform, SharedUnit};
use std::mem::discriminant as mem_entity;
pub fn is_valid_transform(name: &str, units: &Vec<SharedUnit>) -> bool {
match name {
"translate" => valid_args_scheme(vec!["length", "length"], &units),
"skew" => valid_args_scheme(vec!["angle", "angle"], &units),
"rotate" => valid_args_scheme(vec!["angle"], &units),
_ => false,
}
}
pub fn valid_args_scheme(scheme: Vec<&str>, source: &Vec<SharedUnit>) -> bool {
if scheme.len() == source.len() {
let mut matches: Vec<bool> = vec![];
for (index, unit_type) in scheme.iter().enumerate() {
let entity = mem_entity(&source[index]);
match unit_type.clone() {
"length" => matches.push(mem_entity(&SharedUnit::Length(Length::Percent(1.0))) == entity),
"angle" => matches.push(mem_entity(&SharedUnit::Angle(Angle::Degrees(1.0))) == entity),
_ => matches.push(false),
}
}
let position_unmatched = matches.iter().position(|matched| !matched);
position_unmatched.is_none()
} else {
false
}
}
pub fn extract_args_by_type(name: &str, source: &Vec<SharedUnit>) -> Transform {
match name {
"translate" => {
let x = extract!(SharedUnit::Length(_), source[0]).unwrap_or(Length::Point(0.));
let y = extract!(SharedUnit::Length(_), source[1]).unwrap_or(Length::Point(0.));
Transform::Translate((x, y))
}
"rotate" => {
let angle = extract!(SharedUnit::Angle(_), source[0]).unwrap_or(Angle::Degrees(0.));
Transform::Rotate(angle)
}
"skew" => {
let x = extract!(SharedUnit::Angle(_), source[0]).unwrap_or(Angle::Degrees(0.));
let y = extract!(SharedUnit::Angle(_), source[1]).unwrap_or(Angle::Degrees(0.));
Transform::Skew((x, y))
}
_ => Transform::None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn validate_args_scheme() {
let units = vec![SharedUnit::Length(Length::Point(1.)), SharedUnit::Length(Length::Point(1.))];
assert!(valid_args_scheme(vec!["length", "length"], &units), true);
let units = vec![SharedUnit::Length(Length::Point(1.)), SharedUnit::Angle(Angle::Degrees(1.))];
assert_eq!(valid_args_scheme(vec!["angle", "length"], &units), false);
assert!(valid_args_scheme(vec!["length", "angle"], &units), true);
}
}