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