1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct XtabML {
6 pub version: String,
7 pub date: Option<String>,
8 pub time: Option<String>,
9 pub origin: Option<String>,
10 pub user: Option<String>,
11
12 pub languages: Vec<Language>,
14
15 pub control_types: Vec<ControlType>,
17
18 pub statistic_types: Vec<StatisticType>,
20
21 pub controls: Vec<Control>,
23
24 pub tables: Vec<Table>,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct Language {
31 pub lang: String,
32 pub base: Option<String>,
33 pub description: String,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct ControlType {
39 pub name: String,
40 pub status: Option<String>,
41 pub text: String,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct StatisticType {
47 pub name: String,
48 pub text: String,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct Control {
54 pub r#type: String,
55 pub text: String,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct Table {
61 pub name: Option<String>,
62 pub title: String,
63
64 pub controls: Vec<Control>,
66
67 pub row_edge: Option<Edge>,
69
70 pub column_edge: Option<Edge>,
72
73 pub statistics: Vec<Statistic>,
75
76 pub data: TableData,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct Edge {
83 pub axis: String, pub groups: Vec<Group>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct Group {
90 pub elements: Vec<Element>,
91 pub summaries: Vec<Summary>,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct Element {
97 pub text: String,
98 pub index: Option<i32>,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct Summary {
104 pub text: String,
105}
106
107#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct Statistic {
110 pub r#type: String,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct TableData {
116 pub rows: Vec<DataRow>,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct DataRowSeries {
122 pub statistic: Option<Statistic>,
123 pub cells: Vec<DataCell>,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct DataRow {
129 pub data_row_series: Vec<DataRowSeries>,
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize)]
134pub struct DataCell {
135 pub value: Option<String>,
136 pub is_missing: bool,
137}
138
139impl Default for DataCell {
140 fn default() -> Self {
141 Self {
142 value: None,
143 is_missing: false,
144 }
145 }
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct StatisticData {
151 pub statistic_type: String,
152 pub values: Vec<Vec<Option<String>>>,
153}
154
155impl Table {
156 pub fn statistic_types(&self) -> Vec<&str> {
158 self.statistics.iter().map(|s| s.r#type.as_str()).collect()
159 }
160
161 pub fn shape(&self) -> (usize, usize) {
163 let rows = self.data.rows.len();
164 let cols = if rows > 0 {
165 self.data.rows[0].data_row_series[0].cells.len()
166 } else {
167 0
168 };
169 (rows, cols)
170 }
171
172 pub fn get_statistic_data(&self, statistic_index: usize) -> Option<Vec<Vec<Option<String>>>> {
174 if statistic_index >= self.statistics.len() {
175 return None;
176 }
177
178 let statistics_count = self.statistics.len();
179 let _values_per_cell = (self.data.rows.len() / statistics_count).max(1);
180
181 let result = Vec::new();
182
183 Some(result)
202 }
203
204 pub fn row_labels(&self) -> Vec<String> {
206 self.row_edge
207 .as_ref()
208 .and_then(|e| e.groups.first())
209 .map(|g| g.elements.iter().map(|e| e.text.clone()).collect())
210 .unwrap_or_default()
211 }
212
213 pub fn column_labels(&self) -> Vec<String> {
215 self.column_edge
216 .as_ref()
217 .and_then(|e| e.groups.first())
218 .map(|g| g.elements.iter().map(|e| e.text.clone()).collect())
219 .unwrap_or_default()
220 }
221}