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
use super::*;
impl From<ArrayDescription> for XCellTyped {
fn from(value: ArrayDescription) -> Self {
Self::Array(Box::new(value))
}
}
impl ArrayDescription {
pub fn parse_cell(&self, cell: &DataType) -> XResult<XCellValue> {
match self.kind {
ArrayKind::Vector2 => self.parse_vec2(cell),
ArrayKind::Vector3 => self.parse_vec3(cell),
ArrayKind::Vector4 => self.parse_vec4(cell),
ArrayKind::Color4 => self.parse_color4(cell),
ArrayKind::Quaternion4 => self.parse_quaternion4(cell),
}
}
fn parse_value(&self, cell: &DataType) -> XResult<Vec<f64>> {
match cell {
DataType::Int(i) => Ok(vec![*i as f64]),
DataType::Float(f) => Ok(vec![*f]),
DataType::String(s) => {
let mut out = vec![];
for item in s.split(',').map(|s| s.trim()) {
if item.is_empty() {
continue;
}
match f64::from_str(item) {
Ok(o) => out.push(o),
Err(_) => return syntax_error(format!("{:?} 无法解析为 decimal 类型", item)),
}
}
Ok(out)
}
DataType::Empty => Ok(self.default.clone()),
_ => syntax_error(format!("{} 无法解析为 decimal 类型", cell)),
}
}
fn parse_vec2(&self, cell: &DataType) -> XResult<XCellValue> {
let vec = self.parse_value(cell)?;
Ok(XCellValue::Vector2(fill_array(&vec)))
}
fn parse_vec3(&self, cell: &DataType) -> XResult<XCellValue> {
let vec = self.parse_value(cell)?;
Ok(XCellValue::Vector3(fill_array(&vec)))
}
fn parse_vec4(&self, cell: &DataType) -> XResult<XCellValue> {
let vec = self.parse_value(cell)?;
Ok(XCellValue::Vector4(fill_array(&vec)))
}
fn parse_color4(&self, cell: &DataType) -> XResult<XCellValue> {
let vec = self.parse_value(cell)?;
Ok(XCellValue::Color4(fill_array(&vec)))
}
fn parse_quaternion4(&self, cell: &DataType) -> XResult<XCellValue> {
let vec = self.parse_value(cell)?;
Ok(XCellValue::Quaternion4(fill_array(&vec)))
}
}
fn fill_array<const N: usize>(vec: &[f64]) -> [f32; N] {
let mut out = [0.0; N];
for (i, v) in vec.iter().enumerate() {
if i >= N {
break;
}
out[i] = *v as f32;
}
out
}