Export settings: node.set takes back what node.get returns (snake_case aliases)

node.get reports an export setting's two-word fields in snake_case, which node.set refused, so a setting could not be read and written back unchanged. ExportSetting now accepts those names as serde aliases; the camelCase names stay the canonical form. Follow-up the maintainer suggested on #2008.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and briefed; Sonnet 5.5 wrote at medium
This commit is contained in:
Trevor BrownandClaude Sonnet 5.5 committed 2026-11-07 19:44:51 -05:00
1 parent 3635c23070
commit 6c3ac0c55b
2 files changed
+37

No files matched your search

+9
View File
@@ -1449,8 +1449,10 @@ pub struct PrintSettings {
/// is printed this far out, to be trimmed off.
pub bleed: f64,
/// Crop marks outside the bleed, at the trim's corners.
#[serde(alias = "crop_marks")]
pub crop_marks: bool,
/// Bleed marks outside the bleed, at the bleed's corners.
#[serde(alias = "bleed_marks")]
pub bleed_marks: bool,
/// CMYK colour (converted from RGB) instead of RGB.
pub cmyk: bool,
@@ -1519,25 +1521,32 @@ pub struct ExportSetting {
pub print: PrintSettings,
/// Only the layer itself (on), or every layer that shows in its area (off).
#[serde(skip_serializing_if = "is_true")]
#[serde(alias = "contents_only")]
pub contents_only: bool,
/// The layer's own box, cutting off what it paints outside it (shadows, outside strokes).
#[serde(skip_serializing_if = "is_false")]
#[serde(alias = "include_bounding_box")]
pub include_bounding_box: bool,
/// SVG: text as outlines (on) or as `<text>` elements (off).
#[serde(skip_serializing_if = "is_true")]
#[serde(alias = "svg_outline_text")]
pub svg_outline_text: bool,
/// SVG: layer names as `id` attributes.
#[serde(skip_serializing_if = "is_false")]
#[serde(alias = "svg_id_attribute")]
pub svg_id_attribute: bool,
/// SVG: strokes as `stroke` attributes where that's exact (on), else as outlines.
#[serde(skip_serializing_if = "is_true")]
#[serde(alias = "svg_simplify_stroke")]
pub svg_simplify_stroke: bool,
/// Android Vector Drawable: what to do with what a drawable can't hold exactly.
#[serde(skip_serializing_if = "VdCompat::is_default")]
#[serde(alias = "vd_compat")]
pub vd_compat: VdCompat,
/// PNG, JPG and WebP: the color profile the file is written in. SVG, PDF and XML are always
/// sRGB, whatever this says.
#[serde(skip_serializing_if = "ExportColorProfile::is_default")]
#[serde(alias = "color_profile")]
pub color_profile: ExportColorProfile,
/// JPG: the encoder's quality, 1 (smallest file) to 100 (see [`ExportSetting::quality`]).
#[serde(skip_serializing_if = "is_default_quality")]
@@ -384,3 +384,31 @@ fn copy_as_png_svg_and_code() {
let css = crate::codegen::code_for(doc, a, crate::codegen::CodeLang::Css);
assert!(css.contains("background: #FF0000;"), "Copy as CSS is the layer's CSS from Inspect");
}
#[test]
fn node_set_takes_back_the_export_settings_node_get_returns() {
let mut s = Session::new();
let a = rect(&mut s, 0.0, 0.0, 40.0, 20.0, "#FF0000", None);
let given = json!({
"format": "jpg",
"suffix": "@3x",
"contentsOnly": false,
"includeBoundingBox": true,
"svgOutlineText": false,
"svgIdAttribute": true,
"svgSimplifyStroke": false,
"vdCompat": "exact",
"colorProfile": "displayP3",
"quality": 55,
"bleed": 9,
"cropMarks": true,
"bleedMarks": true,
});
ex(&mut s, "export.add", json!({"ids": [a], "setting": given}));
let stored = s.doc().unwrap().node(a).unwrap().exports.clone();
assert_eq!(stored.len(), 1);
let got = ex(&mut s, "node.get", json!({"id": a}))["exports"].clone();
set(&mut s, &[a], json!({"exports": []}));
set(&mut s, &[a], json!({"exports": got}));
assert_eq!(s.doc().unwrap().node(a).unwrap().exports, stored, "node.set stores what node.get returned, unchanged");
}