Skip to main content

spreadsheet_kit/tools/
write_normalize.rs

1use crate::core::write::{normalize_object_edit, normalize_shorthand_edit};
2use crate::errors::InvalidParamsError;
3use crate::model::{FormulaParsePolicy, Warning};
4use crate::tools::fork::{CellEdit, EditBatchParams};
5use anyhow::Result;
6use schemars::JsonSchema;
7use serde::Deserialize;
8
9#[derive(Debug, Clone, Deserialize, JsonSchema)]
10pub struct EditBatchParamsInput {
11    pub fork_id: String,
12    pub sheet_name: String,
13    pub edits: Vec<CellEditInput>,
14    #[serde(default)]
15    pub formula_parse_policy: Option<FormulaParsePolicy>,
16}
17
18#[derive(Debug, Clone, Deserialize, JsonSchema)]
19#[serde(untagged)]
20pub enum CellEditInput {
21    Shorthand(String),
22    Object(CellEditV2),
23}
24
25#[derive(Debug, Clone, Deserialize, JsonSchema)]
26pub struct CellEditV2 {
27    pub address: String,
28    #[serde(default)]
29    pub value: Option<String>,
30    #[serde(default)]
31    pub formula: Option<String>,
32    #[serde(default)]
33    pub is_formula: Option<bool>,
34}
35
36pub fn normalize_edit_batch(
37    params: EditBatchParamsInput,
38) -> Result<(EditBatchParams, Vec<Warning>)> {
39    let mut warnings = Vec::new();
40    let mut edits = Vec::with_capacity(params.edits.len());
41
42    for (idx, edit) in params.edits.into_iter().enumerate() {
43        match edit {
44            CellEditInput::Shorthand(entry) => {
45                let (normalized, core_warnings) =
46                    normalize_shorthand_edit(&entry).map_err(|err| {
47                        InvalidParamsError::new("edit_batch", err.to_string())
48                            .with_path(format!("edits[{idx}]"))
49                    })?;
50                edits.push(CellEdit {
51                    address: normalized.address,
52                    value: normalized.value,
53                    is_formula: normalized.is_formula,
54                });
55                warnings.extend(core_warnings.into_iter().map(|warning| Warning {
56                    code: warning.code,
57                    message: warning.message,
58                }));
59            }
60            CellEditInput::Object(obj) => {
61                let normalized =
62                    normalize_object_edit(&obj.address, obj.value, obj.formula, obj.is_formula)
63                        .map_err(|err| {
64                            let path = if err.to_string().contains("address") {
65                                format!("edits[{idx}].address")
66                            } else {
67                                format!("edits[{idx}]")
68                            };
69                            InvalidParamsError::new("edit_batch", err.to_string()).with_path(path)
70                        })?;
71
72                edits.push(CellEdit {
73                    address: normalized.0.address,
74                    value: normalized.0.value,
75                    is_formula: normalized.0.is_formula,
76                });
77                warnings.extend(normalized.1.into_iter().map(|warning| Warning {
78                    code: warning.code,
79                    message: warning.message,
80                }));
81            }
82        }
83    }
84
85    Ok((
86        EditBatchParams {
87            fork_id: params.fork_id,
88            sheet_name: params.sheet_name,
89            edits,
90        },
91        warnings,
92    ))
93}