让节点 offset 在反序列化时缺省成零偏移
ui_editor/layout/node.rs 给 Node.offset 加 #[serde(default)],历史设计文档缺该字段时按零偏移解析 ui_editor/persistence.rs 补 legacy_nodes_without_offset_field_fall_back_to_zero_offset 锁定该回退口径
This commit is contained in:
@@ -15,6 +15,8 @@ pub struct Node {
|
||||
pub component: Option<Component>,
|
||||
pub children_display_mode: ChildrenDisplayMode,
|
||||
pub children: Vec<Node>,
|
||||
// 偏移量是后加的字段:历史设计文档没有它,默认回落到零偏移,保证旧文档仍可读。
|
||||
#[serde(default)]
|
||||
pub offset: NodeOffset,
|
||||
}
|
||||
|
||||
|
||||
@@ -832,6 +832,7 @@ fn validate_id(value: &str, label: &str) -> Result<(), String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ui_editor::layout::offset::NodeOffset;
|
||||
|
||||
const PROJECT_ID: &str = "ui-design-persistence-project";
|
||||
|
||||
@@ -1444,6 +1445,43 @@ mod tests {
|
||||
.is_err());
|
||||
}
|
||||
|
||||
/// 历史设计文档没有节点 `offset` 字段:缺字段必须按零偏移解析,不能判成缺字段损坏。
|
||||
#[test]
|
||||
fn legacy_nodes_without_offset_field_fall_back_to_zero_offset() {
|
||||
let mut value = serde_json::to_value(state_with_sprite_and_dragged_transform())
|
||||
.expect("serialize dragged UI design state");
|
||||
strip_offset_fields(&mut value);
|
||||
let state: State = serde_json::from_value(value).expect("节点缺 offset 时仍可解析");
|
||||
assert_eq!(
|
||||
state.ui_trees[0].root.offset,
|
||||
NodeOffset::default(),
|
||||
"根节点缺 offset 时回落零偏移"
|
||||
);
|
||||
assert_eq!(
|
||||
state.ui_trees[0].root.children[0].offset,
|
||||
NodeOffset::default(),
|
||||
"子节点缺 offset 时回落零偏移"
|
||||
);
|
||||
}
|
||||
|
||||
/// 递归删除夹具里所有节点级 `offset` 字段,模拟该字段引入前落盘的文档。
|
||||
fn strip_offset_fields(value: &mut serde_json::Value) {
|
||||
match value {
|
||||
serde_json::Value::Object(fields) => {
|
||||
fields.remove("offset");
|
||||
for field in fields.values_mut() {
|
||||
strip_offset_fields(field);
|
||||
}
|
||||
}
|
||||
serde_json::Value::Array(items) => {
|
||||
for item in items {
|
||||
strip_offset_fields(item);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_text_component_with_missing_font_asset() {
|
||||
let (directory, asset_id) = fixture();
|
||||
|
||||
Reference in New Issue
Block a user