1use crate::caps::BackendCaps;
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4use std::collections::BTreeMap;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema, Default)]
7#[serde(transparent)]
8pub struct WorkbookId(pub String);
9
10impl WorkbookId {
11 pub fn as_str(&self) -> &str {
12 &self.0
13 }
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
17pub struct Warning {
18 pub code: String,
19 pub message: String,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
23pub struct WorkbookDescriptor {
24 pub workbook_id: WorkbookId,
25 pub short_id: String,
26 pub slug: String,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub folder: Option<String>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub path: Option<String>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub client_path: Option<String>,
33 pub bytes: u64,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub last_modified: Option<String>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub revision_id: Option<String>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub caps: Option<BackendCaps>,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
43pub struct WorkbookListResponse {
44 pub workbooks: Vec<WorkbookDescriptor>,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub next_offset: Option<u32>,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
50pub struct WorkbookDescription {
51 pub workbook_id: WorkbookId,
52 pub short_id: String,
53 pub slug: String,
54 pub path: String,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub client_path: Option<String>,
57 pub bytes: u64,
58 pub sheet_count: usize,
59 pub defined_names: usize,
60 pub tables: usize,
61 pub macros_present: bool,
62 pub last_modified: Option<String>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub revision_id: Option<String>,
65 pub caps: BackendCaps,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
69pub struct WorkbookSummaryResponse {
70 pub workbook_id: WorkbookId,
71 pub workbook_short_id: String,
72 pub slug: String,
73 pub sheet_count: usize,
74 pub total_cells: u64,
75 pub total_formulas: u64,
76 pub breakdown: WorkbookBreakdown,
77 pub region_counts: RegionCountSummary,
78 #[serde(skip_serializing_if = "Vec::is_empty")]
79 pub key_named_ranges: Vec<NamedRangeDescriptor>,
80 #[serde(skip_serializing_if = "Vec::is_empty")]
81 pub suggested_entry_points: Vec<EntryPoint>,
82 #[serde(skip_serializing_if = "Vec::is_empty")]
83 pub notes: Vec<String>,
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
87pub struct WorkbookBreakdown {
88 pub data_sheets: u32,
89 pub calculator_sheets: u32,
90 pub parameter_sheets: u32,
91 pub metadata_sheets: u32,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
95pub struct RegionCountSummary {
96 pub data: u32,
97 pub parameters: u32,
98 pub outputs: u32,
99 pub calculator: u32,
100 pub metadata: u32,
101 pub other: u32,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
105pub struct EntryPoint {
106 pub sheet_name: String,
107 pub region_id: Option<u32>,
108 pub bounds: Option<String>,
109 pub rationale: String,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
113pub struct SheetSummary {
114 pub name: String,
115 pub visible: bool,
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub row_count: Option<u32>,
118 #[serde(skip_serializing_if = "Option::is_none")]
119 pub column_count: Option<u32>,
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub non_empty_cells: Option<u32>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub formula_cells: Option<u32>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub cached_values: Option<u32>,
126 pub classification: SheetClassification,
127 #[serde(skip_serializing_if = "Vec::is_empty")]
128 pub style_tags: Vec<String>,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
132#[serde(rename_all = "snake_case")]
133pub enum SheetClassification {
134 Data,
135 Calculator,
136 Mixed,
137 Metadata,
138 Empty,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
142pub struct SheetListResponse {
143 pub workbook_id: WorkbookId,
144 pub workbook_short_id: String,
145 pub sheets: Vec<SheetSummary>,
146 #[serde(skip_serializing_if = "Option::is_none")]
147 pub next_offset: Option<u32>,
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
151pub struct SheetOverviewResponse {
152 pub workbook_id: WorkbookId,
153 pub workbook_short_id: String,
154 pub sheet_name: String,
155 pub narrative: String,
156 pub regions: Vec<SheetRegion>,
157 pub detected_regions: Vec<DetectedRegion>,
158 pub detected_region_count: u32,
159 pub detected_regions_truncated: bool,
160 pub key_ranges: Vec<String>,
161 pub formula_ratio: f32,
162 pub notable_features: Vec<String>,
163 pub notes: Vec<String>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
167pub struct SheetRegion {
168 pub kind: RegionKind,
169 pub address: String,
170 pub description: String,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
174pub enum RegionKind {
175 #[serde(rename = "likely_table")]
176 Table,
177 #[serde(rename = "likely_data")]
178 Data,
179 #[serde(rename = "likely_parameters")]
180 Parameters,
181 #[serde(rename = "likely_outputs")]
182 Outputs,
183 #[serde(rename = "likely_calculator")]
184 Calculator,
185 #[serde(rename = "likely_metadata")]
186 Metadata,
187 #[serde(rename = "likely_styles")]
188 Styles,
189 #[serde(rename = "likely_comments")]
190 Comments,
191 #[serde(rename = "unknown")]
192 Other,
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
196pub struct DetectedRegion {
197 pub id: u32,
198 pub bounds: String,
199 pub header_row: Option<u32>,
200 pub headers: Vec<String>,
201 pub header_count: u32,
202 pub headers_truncated: bool,
203 pub row_count: u32,
204 pub classification: RegionKind,
205 pub region_kind: Option<RegionKind>,
206 pub confidence: f32,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
210pub struct SheetPageResponse {
211 pub workbook_id: WorkbookId,
212 pub workbook_short_id: String,
213 pub sheet_name: String,
214 #[serde(skip_serializing_if = "Vec::is_empty")]
215 pub rows: Vec<RowSnapshot>,
216 #[serde(skip_serializing_if = "Option::is_none")]
217 pub next_start_row: Option<u32>,
218 #[serde(skip_serializing_if = "Option::is_none")]
219 pub header_row: Option<RowSnapshot>,
220 #[serde(skip_serializing_if = "Option::is_none")]
221 pub compact: Option<SheetPageCompact>,
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub values_only: Option<SheetPageValues>,
224 pub format: SheetPageFormat,
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
228pub struct RowSnapshot {
229 pub row_index: u32,
230 pub cells: Vec<CellSnapshot>,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
234pub struct CellSnapshot {
235 pub address: String,
236 pub value: Option<CellValue>,
237 pub formula: Option<String>,
238 pub cached_value: Option<CellValue>,
239 pub number_format: Option<String>,
240 pub style_tags: Vec<String>,
241 pub notes: Vec<String>,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
245#[serde(tag = "kind", content = "value")]
246pub enum CellValue {
247 Text(String),
248 Number(f64),
249 Bool(bool),
250 Error(String),
251 Date(String),
252}
253
254#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
255#[serde(rename_all = "snake_case")]
256pub enum CellValueKind {
257 Text,
258 Number,
259 Bool,
260 Error,
261 Date,
262}
263
264#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
265#[serde(untagged)]
266pub enum CellValuePrimitive {
267 Text(String),
268 Number(f64),
269 Bool(bool),
270}
271
272#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
273#[serde(rename_all = "snake_case")]
274pub enum TableOutputFormat {
275 Json,
276 Values,
277 Csv,
278}
279
280#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, Default)]
281#[serde(rename_all = "snake_case")]
282pub enum SheetPageFormat {
283 #[default]
284 Full,
285 Compact,
286 ValuesOnly,
287}
288
289#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
290pub struct SheetPageCompact {
291 pub headers: Vec<String>,
292 pub header_row: Vec<Option<CellValue>>,
293 pub rows: Vec<Vec<Option<CellValue>>>,
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
297pub struct SheetPageValues {
298 pub rows: Vec<Vec<Option<CellValue>>>,
299}
300
301#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
302pub struct SheetStatisticsResponse {
303 pub workbook_id: WorkbookId,
304 pub workbook_short_id: String,
305 pub sheet_name: String,
306 pub row_count: u32,
307 pub column_count: u32,
308 pub density: f32,
309 #[serde(skip_serializing_if = "Vec::is_empty")]
310 pub numeric_columns: Vec<ColumnSummary>,
311 #[serde(skip_serializing_if = "Vec::is_empty")]
312 pub text_columns: Vec<ColumnSummary>,
313 pub null_counts: BTreeMap<String, u32>,
314 pub duplicate_warnings: Vec<String>,
315}
316
317#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
318pub struct ColumnSummary {
319 pub header: Option<String>,
320 pub column: String,
321 #[serde(skip_serializing_if = "Vec::is_empty")]
322 pub samples: Vec<CellValue>,
323 pub min: Option<f64>,
324 pub max: Option<f64>,
325 pub mean: Option<f64>,
326}
327
328#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
329pub struct SheetFormulaMapResponse {
330 pub workbook_id: WorkbookId,
331 pub workbook_short_id: String,
332 pub sheet_name: String,
333 pub groups: Vec<FormulaGroup>,
334 #[serde(skip_serializing_if = "Option::is_none")]
335 pub next_offset: Option<u32>,
336}
337
338#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
339pub struct FormulaGroup {
340 pub fingerprint: String,
341 #[serde(skip_serializing_if = "Vec::is_empty")]
342 pub addresses: Vec<String>,
343 #[serde(skip_serializing_if = "Option::is_none")]
344 pub count: Option<u32>,
345 pub formula: String,
346 pub is_array: bool,
347 pub is_shared: bool,
348 pub is_volatile: bool,
349}
350
351#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
352pub struct FormulaTraceResponse {
353 pub workbook_id: WorkbookId,
354 pub workbook_short_id: String,
355 pub sheet_name: String,
356 pub origin: String,
357 pub direction: TraceDirection,
358 pub layers: Vec<TraceLayer>,
359 pub next_cursor: Option<TraceCursor>,
360 pub notes: Vec<String>,
361}
362
363#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
364pub struct FormulaTraceEdge {
365 pub from: String,
366 pub to: String,
367 pub formula: Option<String>,
368 pub note: Option<String>,
369}
370
371#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
372pub struct TraceLayer {
373 pub depth: u32,
374 pub summary: TraceLayerSummary,
375 pub highlights: TraceLayerHighlights,
376 pub edges: Vec<FormulaTraceEdge>,
377 pub has_more: bool,
378}
379
380#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
381pub struct TraceLayerSummary {
382 pub total_nodes: usize,
383 pub formula_nodes: usize,
384 pub value_nodes: usize,
385 pub blank_nodes: usize,
386 pub external_nodes: usize,
387 pub unique_formula_groups: usize,
388}
389
390#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
391pub struct TraceLayerHighlights {
392 pub top_ranges: Vec<TraceRangeHighlight>,
393 pub top_formula_groups: Vec<TraceFormulaGroupHighlight>,
394 pub notable_cells: Vec<TraceCellHighlight>,
395}
396
397#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
398pub struct TraceRangeHighlight {
399 pub start: String,
400 pub end: String,
401 pub count: usize,
402 pub literals: usize,
403 pub formulas: usize,
404 pub blanks: usize,
405 pub sample_values: Vec<CellValue>,
406 pub sample_formulas: Vec<String>,
407 pub sample_addresses: Vec<String>,
408}
409
410#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
411pub struct TraceFormulaGroupHighlight {
412 pub fingerprint: String,
413 pub formula: String,
414 pub count: usize,
415 pub sample_addresses: Vec<String>,
416}
417
418#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
419pub struct TraceCellHighlight {
420 pub address: String,
421 pub kind: TraceCellKind,
422 pub value: Option<CellValue>,
423 pub formula: Option<String>,
424}
425
426#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash)]
427#[serde(rename_all = "snake_case")]
428pub enum TraceCellKind {
429 Formula,
430 Literal,
431 Blank,
432 External,
433}
434
435#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
436pub struct TraceCursor {
437 pub depth: u32,
438 pub offset: usize,
439}
440
441#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
442#[serde(rename_all = "snake_case")]
443pub enum TraceDirection {
444 Precedents,
445 Dependents,
446}
447
448#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
449pub struct NamedRangeDescriptor {
450 pub name: String,
451 pub scope: Option<String>,
452 pub refers_to: String,
453 pub kind: NamedItemKind,
454 pub sheet_name: Option<String>,
455 pub comment: Option<String>,
456}
457
458#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
459#[serde(rename_all = "snake_case")]
460pub enum NamedItemKind {
461 NamedRange,
462 Table,
463 Formula,
464 Unknown,
465}
466
467#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
468pub struct NamedRangesResponse {
469 pub workbook_id: WorkbookId,
470 pub workbook_short_id: String,
471 pub items: Vec<NamedRangeDescriptor>,
472}
473
474#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
475pub struct FindFormulaMatch {
476 pub address: String,
477 pub sheet_name: String,
478 pub formula: String,
479 pub cached_value: Option<CellValue>,
480 pub context: Vec<RowSnapshot>,
481}
482
483#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
484pub struct FindFormulaResponse {
485 pub workbook_id: WorkbookId,
486 pub workbook_short_id: String,
487 pub matches: Vec<FindFormulaMatch>,
488 #[serde(skip_serializing_if = "Option::is_none")]
489 pub next_offset: Option<u32>,
490}
491
492#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
493pub struct VolatileScanEntry {
494 pub address: String,
495 pub sheet_name: String,
496 pub function: String,
497 pub note: Option<String>,
498}
499
500#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
501pub struct VolatileScanResponse {
502 pub workbook_id: WorkbookId,
503 pub workbook_short_id: String,
504 pub items: Vec<VolatileScanEntry>,
505 #[serde(skip_serializing_if = "Option::is_none")]
506 pub next_offset: Option<u32>,
507}
508
509#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
510pub struct StyleDescriptor {
511 pub font: Option<FontDescriptor>,
512 pub fill: Option<FillDescriptor>,
513 pub borders: Option<BordersDescriptor>,
514 pub alignment: Option<AlignmentDescriptor>,
515 pub number_format: Option<String>,
516}
517
518#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
519pub struct FontDescriptor {
520 pub name: Option<String>,
521 pub size: Option<f64>,
522 pub bold: Option<bool>,
523 pub italic: Option<bool>,
524 pub underline: Option<String>,
525 pub strikethrough: Option<bool>,
526 pub color: Option<String>,
527}
528
529#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
530#[serde(tag = "kind", rename_all = "snake_case")]
531pub enum FillDescriptor {
532 Pattern(PatternFillDescriptor),
533 Gradient(GradientFillDescriptor),
534}
535
536#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
537pub struct PatternFillDescriptor {
538 pub pattern_type: Option<String>,
539 pub foreground_color: Option<String>,
540 pub background_color: Option<String>,
541}
542
543#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
544pub struct GradientFillDescriptor {
545 pub degree: Option<f64>,
546 pub stops: Vec<GradientStopDescriptor>,
547}
548
549#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
550pub struct GradientStopDescriptor {
551 pub position: f64,
552 pub color: String,
553}
554
555#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
556pub struct BordersDescriptor {
557 pub left: Option<BorderSideDescriptor>,
558 pub right: Option<BorderSideDescriptor>,
559 pub top: Option<BorderSideDescriptor>,
560 pub bottom: Option<BorderSideDescriptor>,
561 pub diagonal: Option<BorderSideDescriptor>,
562 pub vertical: Option<BorderSideDescriptor>,
563 pub horizontal: Option<BorderSideDescriptor>,
564 pub diagonal_up: Option<bool>,
565 pub diagonal_down: Option<bool>,
566}
567
568#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
569pub struct BorderSideDescriptor {
570 pub style: Option<String>,
571 pub color: Option<String>,
572}
573
574#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
575pub struct AlignmentDescriptor {
576 pub horizontal: Option<String>,
577 pub vertical: Option<String>,
578 pub wrap_text: Option<bool>,
579 pub text_rotation: Option<u32>,
580}
581
582#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
587pub struct StylePatch {
588 #[serde(default)]
589 pub font: Option<Option<FontPatch>>,
590 #[serde(default)]
591 pub fill: Option<Option<FillPatch>>,
592 #[serde(default)]
593 pub borders: Option<Option<BordersPatch>>,
594 #[serde(default)]
595 pub alignment: Option<Option<AlignmentPatch>>,
596 #[serde(default)]
597 pub number_format: Option<Option<String>>,
598}
599
600#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
601pub struct FontPatch {
602 #[serde(default)]
603 pub name: Option<Option<String>>,
604 #[serde(default)]
605 pub size: Option<Option<f64>>,
606 #[serde(default)]
607 pub bold: Option<Option<bool>>,
608 #[serde(default)]
609 pub italic: Option<Option<bool>>,
610 #[serde(default)]
611 pub underline: Option<Option<String>>,
612 #[serde(default)]
613 pub strikethrough: Option<Option<bool>>,
614 #[serde(default)]
615 pub color: Option<Option<String>>,
616}
617
618#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
619#[serde(tag = "kind", rename_all = "snake_case")]
620pub enum FillPatch {
621 Pattern(PatternFillPatch),
622 Gradient(GradientFillPatch),
623}
624
625#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
626pub struct PatternFillPatch {
627 #[serde(default)]
628 pub pattern_type: Option<Option<String>>,
629 #[serde(default)]
630 pub foreground_color: Option<Option<String>>,
631 #[serde(default)]
632 pub background_color: Option<Option<String>>,
633}
634
635#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
636pub struct GradientFillPatch {
637 #[serde(default)]
638 pub degree: Option<Option<f64>>,
639 #[serde(default)]
640 pub stops: Option<Vec<GradientStopPatch>>,
641}
642
643#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
644pub struct GradientStopPatch {
645 pub position: f64,
646 pub color: String,
647}
648
649#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
650pub struct BordersPatch {
651 #[serde(default)]
652 pub left: Option<Option<BorderSidePatch>>,
653 #[serde(default)]
654 pub right: Option<Option<BorderSidePatch>>,
655 #[serde(default)]
656 pub top: Option<Option<BorderSidePatch>>,
657 #[serde(default)]
658 pub bottom: Option<Option<BorderSidePatch>>,
659 #[serde(default)]
660 pub diagonal: Option<Option<BorderSidePatch>>,
661 #[serde(default)]
662 pub vertical: Option<Option<BorderSidePatch>>,
663 #[serde(default)]
664 pub horizontal: Option<Option<BorderSidePatch>>,
665 #[serde(default)]
666 pub diagonal_up: Option<Option<bool>>,
667 #[serde(default)]
668 pub diagonal_down: Option<Option<bool>>,
669}
670
671#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
672pub struct BorderSidePatch {
673 #[serde(default)]
674 pub style: Option<Option<String>>,
675 #[serde(default)]
676 pub color: Option<Option<String>>,
677}
678
679#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
680pub struct AlignmentPatch {
681 #[serde(default)]
682 pub horizontal: Option<Option<String>>,
683 #[serde(default)]
684 pub vertical: Option<Option<String>>,
685 #[serde(default)]
686 pub wrap_text: Option<Option<bool>>,
687 #[serde(default)]
688 pub text_rotation: Option<Option<u32>>,
689}
690
691#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
692pub struct SheetStylesResponse {
693 pub workbook_id: WorkbookId,
694 pub workbook_short_id: String,
695 pub sheet_name: String,
696 pub styles: Vec<StyleSummary>,
697 #[serde(skip_serializing_if = "Vec::is_empty")]
698 pub conditional_rules: Vec<String>,
699 pub total_styles: u32,
700 pub styles_truncated: bool,
701}
702
703#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
704pub struct StyleSummary {
705 pub style_id: String,
706 pub occurrences: u32,
707 pub tags: Vec<String>,
708 #[serde(skip_serializing_if = "Vec::is_empty")]
709 pub example_cells: Vec<String>,
710 pub descriptor: Option<StyleDescriptor>,
711 #[serde(skip_serializing_if = "Vec::is_empty")]
712 pub cell_ranges: Vec<String>,
713 pub ranges_truncated: bool,
714}
715
716#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
717pub struct WorkbookStyleSummaryResponse {
718 pub workbook_id: WorkbookId,
719 pub workbook_short_id: String,
720 #[serde(skip_serializing_if = "Option::is_none")]
721 pub theme: Option<ThemeSummary>,
722 #[serde(skip_serializing_if = "Option::is_none")]
723 pub inferred_default_style_id: Option<String>,
724 #[serde(skip_serializing_if = "Option::is_none")]
725 pub inferred_default_font: Option<FontDescriptor>,
726 pub styles: Vec<WorkbookStyleUsage>,
727 pub total_styles: u32,
728 pub styles_truncated: bool,
729 #[serde(skip_serializing_if = "Vec::is_empty")]
730 pub conditional_formats: Vec<ConditionalFormatSummary>,
731 pub conditional_formats_truncated: bool,
732 pub scan_truncated: bool,
733 #[serde(skip_serializing_if = "Vec::is_empty")]
734 pub notes: Vec<String>,
735}
736
737#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
738pub struct WorkbookStyleUsage {
739 pub style_id: String,
740 pub occurrences: u32,
741 pub tags: Vec<String>,
742 #[serde(skip_serializing_if = "Vec::is_empty")]
743 pub example_cells: Vec<String>,
744 pub descriptor: Option<StyleDescriptor>,
745}
746
747#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
748pub struct ThemeSummary {
749 pub name: Option<String>,
750 pub colors: BTreeMap<String, String>,
751 pub font_scheme: ThemeFontSchemeSummary,
752}
753
754#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
755pub struct ThemeFontSchemeSummary {
756 pub major_latin: Option<String>,
757 pub major_east_asian: Option<String>,
758 pub major_complex_script: Option<String>,
759 pub minor_latin: Option<String>,
760 pub minor_east_asian: Option<String>,
761 pub minor_complex_script: Option<String>,
762}
763
764#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
765pub struct ConditionalFormatSummary {
766 pub sheet_name: String,
767 pub range: String,
768 pub rule_types: Vec<String>,
769 pub rule_count: u32,
770}
771
772#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
773pub struct ManifestStubResponse {
774 pub workbook_id: WorkbookId,
775 pub workbook_short_id: String,
776 pub slug: String,
777 pub sheets: Vec<ManifestSheetStub>,
778}
779
780#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
781pub struct ManifestSheetStub {
782 pub sheet_name: String,
783 pub classification: SheetClassification,
784 pub candidate_expectations: Vec<String>,
785 pub notes: Vec<String>,
786}
787
788#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
789#[serde(rename_all = "snake_case")]
790pub enum FindMode {
791 #[default]
792 Value,
793 Label,
794}
795
796#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
797#[serde(rename_all = "snake_case")]
798pub enum LabelDirection {
799 Right,
800 Below,
801 Any,
802}
803
804#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
805pub struct FindValueMatch {
806 pub address: String,
807 pub sheet_name: String,
808 pub value: Option<CellValue>,
809 pub row_context: Option<RowContext>,
810 pub neighbors: Option<NeighborValues>,
811 pub label_hit: Option<LabelHit>,
812}
813
814#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
815pub struct RowContext {
816 pub headers: Vec<String>,
817 pub values: Vec<Option<CellValue>>,
818}
819
820#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
821pub struct NeighborValues {
822 pub left: Option<CellValue>,
823 pub right: Option<CellValue>,
824 pub up: Option<CellValue>,
825 pub down: Option<CellValue>,
826}
827
828#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
829pub struct LabelHit {
830 pub label_address: String,
831 pub label: String,
832}
833
834#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
835pub struct FindValueResponse {
836 pub workbook_id: WorkbookId,
837 pub workbook_short_id: String,
838 pub matches: Vec<FindValueMatch>,
839 #[serde(skip_serializing_if = "Option::is_none")]
840 pub next_offset: Option<u32>,
841}
842
843pub type TableRow = BTreeMap<String, Option<CellValue>>;
844
845#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
846pub struct ReadTableResponse {
847 pub workbook_id: WorkbookId,
848 pub workbook_short_id: String,
849 pub sheet_name: String,
850 pub table_name: Option<String>,
851 #[serde(skip_serializing_if = "Vec::is_empty")]
852 pub warnings: Vec<Warning>,
853 #[serde(skip_serializing_if = "Vec::is_empty")]
854 pub headers: Vec<String>,
855 #[serde(skip_serializing_if = "Vec::is_empty")]
856 pub rows: Vec<TableRow>,
857 #[serde(skip_serializing_if = "Option::is_none")]
858 pub values: Option<Vec<Vec<Option<CellValuePrimitive>>>>,
859 #[serde(skip_serializing_if = "Option::is_none")]
860 pub types: Option<Vec<Vec<Option<CellValueKind>>>>,
861 #[serde(skip_serializing_if = "Option::is_none")]
862 pub csv: Option<String>,
863 pub total_rows: u32,
864 #[serde(skip_serializing_if = "Option::is_none")]
865 pub next_offset: Option<u32>,
866}
867
868#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
869pub struct ColumnTypeSummary {
870 pub name: String,
871 pub inferred_type: String,
872 pub nulls: u32,
873 pub distinct: u32,
874 pub top_values: Vec<String>,
875 pub min: Option<f64>,
876 pub max: Option<f64>,
877 pub mean: Option<f64>,
878}
879
880#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
881pub struct TableProfileResponse {
882 pub workbook_id: WorkbookId,
883 pub workbook_short_id: String,
884 pub sheet_name: String,
885 pub table_name: Option<String>,
886 pub headers: Vec<String>,
887 pub column_types: Vec<ColumnTypeSummary>,
888 pub row_count: u32,
889 #[serde(skip_serializing_if = "Vec::is_empty")]
890 pub samples: Vec<TableRow>,
891 #[serde(skip_serializing_if = "Vec::is_empty")]
892 pub notes: Vec<String>,
893}
894
895#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
896pub struct RangeValuesResponse {
897 pub workbook_id: WorkbookId,
898 pub workbook_short_id: String,
899 pub sheet_name: String,
900 #[serde(skip_serializing_if = "Vec::is_empty")]
901 pub warnings: Vec<Warning>,
902 pub values: Vec<RangeValuesEntry>,
903}
904
905#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
906pub struct RangeValuesEntry {
907 pub range: String,
908 #[serde(skip_serializing_if = "Option::is_none")]
909 pub rows: Option<Vec<Vec<Option<CellValue>>>>,
910 #[serde(skip_serializing_if = "Option::is_none")]
911 pub values: Option<Vec<Vec<Option<CellValuePrimitive>>>>,
912 #[serde(skip_serializing_if = "Option::is_none")]
913 pub csv: Option<String>,
914 #[serde(skip_serializing_if = "Option::is_none")]
915 pub next_start_row: Option<u32>,
916}
917
918#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
919pub struct CloseWorkbookResponse {
920 pub workbook_id: WorkbookId,
921 pub message: String,
922}
923
924#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
925pub struct VbaProjectSummaryResponse {
926 pub workbook_id: WorkbookId,
927 pub workbook_short_id: String,
928 pub has_vba: bool,
929 pub code_page: Option<u16>,
930 pub sys_kind: Option<String>,
931 pub modules: Vec<VbaModuleDescriptor>,
932 pub modules_truncated: bool,
933 pub references: Vec<VbaReferenceDescriptor>,
934 pub references_truncated: bool,
935 pub notes: Vec<String>,
936}
937
938#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
939pub struct VbaModuleDescriptor {
940 pub name: String,
941 pub stream_name: String,
942 pub doc_string: String,
943 pub text_offset: u64,
944 pub help_context: u32,
945 pub module_type: String,
946 pub read_only: bool,
947 pub private: bool,
948}
949
950#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
951pub struct VbaReferenceDescriptor {
952 pub kind: String,
953 pub debug: String,
954}
955
956#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
957pub struct VbaModuleSourceResponse {
958 pub workbook_id: WorkbookId,
959 pub workbook_short_id: String,
960 pub module_name: String,
961 pub offset_lines: u32,
962 pub limit_lines: u32,
963 pub total_lines: u32,
964 pub truncated: bool,
965 pub source: String,
966}