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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use crate::{
config::{ProjectConfig, TableLineMode},
CalamineTable, XArrayTable, XEnumerateTable,
};
use super::*;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct XCellHeader {
pub column: usize,
pub summary: String,
pub details: String,
pub typing: XCellTyped,
pub field_name: String,
}
impl XCellHeader {
pub fn parse_cell(&self, row: &[DataType]) -> XResult<XCellValueKind> {
match row.get(self.column) {
Some(cell) => self.typing.parse_cell(cell),
None => Err(XError::table_error("无法读取数据")),
}
}
fn try_read_table_kind(table: &CalamineTable, project: &ProjectConfig) -> Option<XTableKind> {
let line = project.line.field.saturating_sub(1) as u32;
let cell = table.get_value((line, 0))?;
match cell.get_string()? {
"enum" => return Some(XTableKind::Enumerate(Box::default())),
"class" => return Some(XTableKind::Class(Box::default())),
_ => {}
}
let line = project.line.typing.saturating_sub(1) as u32;
let cell = table.get_value((line, 0))?;
match XCellTyped::parse(cell.get_string()?, &project.typing) {
XCellTyped::Integer(_) => Some(XTableKind::Array(Box::default())),
XCellTyped::String(_) => None,
_ => {
log::error!("invalid type");
None
}
}
}
}
impl XTableKind {
pub fn read_table_kind(&mut self, table: &CalamineTable, project: &ProjectConfig) {
if let Some(s) = XCellHeader::try_read_table_kind(table, project) {
*self = s
}
}
pub fn read_table_headers(&mut self, table: &CalamineTable, project: &ProjectConfig) {
self.read_table_kind(table, project);
let res = match self {
XTableKind::Array(v) => v.read_table_headers(table, project),
XTableKind::Enumerate(v) => v.read_table_headers(table, project),
XTableKind::Class(_) => {
return;
}
XTableKind::Dictionary(_) => {
todo!()
}
};
match res {
Ok(_) => {}
Err(_) => {}
}
}
}
impl XArrayTable {
pub fn read_table_headers(&mut self, table: &CalamineTable, project: &ProjectConfig) -> XResult<()> {
let line = project.line.typing;
let row = match table.rows().take(line).last() {
Some(s) => s,
None => return Err(XError::table_error(format!("找不到描述, 第 {} 行格式非法", line))),
};
for (i, data) in row.iter().enumerate() {
if data.is_empty() {
continue;
}
self.read_valid_header(table, i, project);
}
Ok(())
}
fn read_valid_header(&mut self, table: &CalamineTable, i: usize, project: &ProjectConfig) -> Option<()> {
let line = project.line.field.saturating_sub(1) as u32;
let field_name = table.get_value((line, i as u32))?.get_string()?;
let line = project.line.typing.saturating_sub(1) as u32;
let field_type = table.get_value((line, i as u32))?.get_string()?;
let typing = XCellTyped::parse(field_type, &project.typing);
let (summary, details) = read_comment_details(table, i, project.line).unwrap_or_default();
self.headers.push(XCellHeader { summary, column: i, typing, field_name: field_name.to_string(), details });
None
}
}
impl XEnumerateTable {
pub fn read_table_headers(&mut self, table: &CalamineTable, project: &ProjectConfig) -> XResult<()> {
let line = project.line.typing;
let row = match table.rows().take(line).last() {
Some(s) => s,
None => return Err(XError::table_error(format!("找不到描述, 第 {} 行格式非法", line))),
};
for (i, data) in row.iter().enumerate() {
if data.is_empty() {
continue;
}
self.read_valid_header(table, i, project);
}
Ok(())
}
fn read_valid_header(&mut self, table: &CalamineTable, i: usize, project: &ProjectConfig) -> Option<()> {
let line = project.line.field.saturating_sub(1) as u32;
let field_name = table.get_value((line, i as u32))?.get_string()?;
let mut set_id = false;
match field_name {
"enum" => return None,
"comment" => {
self.comment_column = i;
return None;
}
"id" => {
self.id_column = i;
set_id = true;
}
_ => {}
}
let line = project.line.typing.saturating_sub(1) as u32;
let field_type = table.get_value((line, i as u32))?.get_string()?;
let typing = XCellTyped::parse(field_type, &project.typing);
match &typing {
XCellTyped::Integer(v) if set_id => {
self.id_type = v.kind;
}
_ => {}
}
let (summary, details) = read_comment_details(table, i, project.line).unwrap_or_default();
self.headers.push(XCellHeader { summary, column: i, typing, field_name: field_name.to_string(), details });
None
}
}
fn read_comment_details(table: &CalamineTable, i: usize, line: TableLineMode) -> Option<(String, String)> {
let line = line.helper.saturating_sub(1) as u32;
let comment = table.get_value((line, i as u32))?;
let summary = comment.to_string();
Some((summary, String::new()))
}