mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-24 10:46:50 -06:00
Format Cells: take the documented camelCase style keys
home.formatCells documents {style: {numFmt?, ...}}, but the style patch
was merged with the style's snake_case field names, so numFmt (and
borders.diagUp/diagDown) were silently ignored. camelCase keys in the
patch are now renamed to the style's own; snake_case keys still work.
This commit is contained in:
@@ -488,7 +488,7 @@ fn borders(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
}
|
||||
|
||||
fn format_cells(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
let Some(patch) = p.get("style").cloned() else {
|
||||
let Some(patch) = p.get("style").map(snake_case_keys) else {
|
||||
// Menu invocation without params: the UI opens the dialog.
|
||||
s.ui_requests.push(crate::UiRequest::Dialog("formatCells".into(), json!({})));
|
||||
return ok();
|
||||
@@ -506,6 +506,32 @@ fn format_cells(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
})
|
||||
}
|
||||
|
||||
/// The style patch with camelCase keys (`numFmt`, `diagDown`, as documented) renamed to the
|
||||
/// style's own snake_case (`num_fmt`, `diag_down`). Keys starting with a capital (`Rgb`) stay.
|
||||
fn snake_case_keys(v: &Json) -> Json {
|
||||
match v {
|
||||
Json::Object(m) => Json::Object(
|
||||
m.iter()
|
||||
.map(|(k, v)| {
|
||||
let key = if k.starts_with(|c: char| c.is_ascii_lowercase()) {
|
||||
k.chars().fold(String::new(), |mut out, c| {
|
||||
if c.is_ascii_uppercase() {
|
||||
out.push('_');
|
||||
}
|
||||
out.push(c.to_ascii_lowercase());
|
||||
out
|
||||
})
|
||||
} else {
|
||||
k.clone()
|
||||
};
|
||||
(key, snake_case_keys(v))
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
other => other.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Deep-merges `patch` into `base` (objects merge, everything else replaces).
|
||||
pub(crate) fn merge_json(mut base: Json, patch: &Json) -> Json {
|
||||
match (&mut base, patch) {
|
||||
@@ -1149,6 +1175,20 @@ mod tests {
|
||||
assert_eq!(adjust_decimals("0%", &v, 1), "0.0%");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_cells_takes_the_documented_keys() {
|
||||
let mut s = crate::Session::new();
|
||||
s.new_workbook();
|
||||
s.execute("cell.set", json!({"cell": "A1", "input": "5"})).unwrap();
|
||||
s.execute("home.formatCells", json!({"range": "A1", "style": {"numFmt": "0.0", "borders": {"diagUp": {"style": "Thin"}}}})).unwrap();
|
||||
let st = &s.execute("cell.get", json!({"cell": "A1"})).unwrap()["style"];
|
||||
assert_eq!(st["num_fmt"], "0.0");
|
||||
assert_eq!(st["borders"]["diag_up"]["style"], "Thin");
|
||||
// The style's own snake_case keys keep working.
|
||||
s.execute("home.formatCells", json!({"range": "A1", "style": {"num_fmt": "0.00"}})).unwrap();
|
||||
assert_eq!(s.execute("cell.get", json!({"cell": "A1"})).unwrap()["style"]["num_fmt"], "0.00");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn width_units() {
|
||||
assert_eq!(chars_to_points(8.43), 64.0);
|
||||
|
||||
Reference in New Issue
Block a user