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
use regex::Regex;
#[derive(Clone, Debug)]
pub enum IceType {
VoidType,
BoolType,
ByteType,
ShortType,
IntType,
LongType,
FloatType,
DoubleType,
StringType,
SequenceType(Box<IceType>),
DictType(Box<IceType>, Box<IceType>),
Optional(Box<IceType>, u8),
CustomType(String)
}
impl IceType {
pub fn from(text: &str) -> Result<IceType, Box<dyn std::error::Error>> {
let type_re = Regex::new(
r#"(?x)
(void) |
(bool) |
(byte) |
(short) |
(int) |
(long) |
(float) |
(double) |
(string) |
(sequence)<(.+)> |
(dictionary)<(.+),\s*(.+)> |
"#
)?;
let captures = type_re.captures(text.trim()).map(|captures| {
captures
.iter()
.skip(1)
.flat_map(|c| c)
.map(|c| c.as_str())
.collect::<Vec<_>>()
});
match captures.as_ref().map(|c| c.as_slice()) {
Some(["void"]) => Ok(IceType::VoidType),
Some(["bool"]) => Ok(IceType::BoolType),
Some(["byte"]) => Ok(IceType::ByteType),
Some(["short"]) => Ok(IceType::ShortType),
Some(["int"]) => Ok(IceType::IntType),
Some(["long"]) => Ok(IceType::LongType),
Some(["float"]) => Ok(IceType::FloatType),
Some(["double"]) => Ok(IceType::DoubleType),
Some(["string"]) => Ok(IceType::StringType),
Some(["sequence", x]) => {
Ok(IceType::SequenceType(Box::new(IceType::from(x)?)))
},
Some(["dictionary", x, y]) => {
Ok(IceType::DictType(Box::new(IceType::from(x)?), Box::new(IceType::from(y)?)))
},
_ => Ok(IceType::CustomType(text.trim().to_string()))
}
}
pub fn rust_type(&self) -> String {
match self {
IceType::VoidType => String::from("()"),
IceType::BoolType => String::from("bool"),
IceType::ByteType => String::from("u8"),
IceType::ShortType => String::from("i16"),
IceType::IntType => String::from("i32"),
IceType::LongType => String::from("i64"),
IceType::FloatType => String::from("f32"),
IceType::DoubleType => String::from("f64"),
IceType::StringType => String::from("String"),
IceType::SequenceType(type_name) => format!("Vec<{}>", type_name.rust_type()),
IceType::DictType(key_type, value_type) => format!("HashMap<{}, {}>", key_type.rust_type(), value_type.rust_type()),
IceType::Optional(type_name, _) => format!("Option<{}>", type_name.rust_type()),
IceType::CustomType(type_name) => format!("{}", type_name),
}
}
pub fn rust_from(&self) -> String {
match self {
IceType::Optional(type_name, _) => format!("Option::<{}>", type_name.rust_type()),
_ => self.rust_type(),
}
}
pub fn as_ref(&self) -> bool {
match self {
IceType::StringType |
IceType::SequenceType(_) |
IceType::DictType(_, _) |
IceType::CustomType(_) => true,
_ => false
}
}
}