mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-13 05:42:38 +00:00
.jam import: board items only on frames, authors without control characters, board items in the dump (#1808)
From the pre-ready review: a sticky or shape item on a non-frame layer is ignored with the warning; the author drops control characters as board.sticky does; dump_samples writes a whiteboard's board items; a doc link made plain text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Model-Effort: Opus 5.5 drove and wrote; Fable 5.1 reviewed
This commit is contained in:
1 parent
4201fed27d
commit
a415598e11
4 files changed
+18
-7
No files matched your search
@@ -56,8 +56,8 @@ pub(super) fn to_rest(msg: &Kv, name: &str, max_nodes: usize) -> (Value, Vec<Str
|
||||
to_rest_for(msg, name, max_nodes, false)
|
||||
}
|
||||
|
||||
/// [`to_rest`] for a FigJam whiteboard (`board`) or a design file: a whiteboard's stickies come
|
||||
/// out as native board items.
|
||||
/// The REST JSON (as `to_rest`) for a FigJam whiteboard (`board`) or a design file: a
|
||||
/// whiteboard's stickies come out as native board items.
|
||||
pub(super) fn to_rest_for(msg: &Kv, name: &str, max_nodes: usize, board: bool) -> (Value, Vec<String>, Vec<Option<VectorNetwork>>) {
|
||||
let mut m = Mapper::new(msg, max_nodes);
|
||||
m.board = board;
|
||||
|
||||
@@ -1583,7 +1583,8 @@ fn dump_samples() {
|
||||
std::fs::write(format!("{out}/{stem}.schema.txt"), txt).unwrap();
|
||||
let msg = schema.decode_message(schema.find("Message").unwrap(), &message).unwrap();
|
||||
std::fs::write(format!("{out}/{stem}.json"), serde_json::to_string_pretty(&debug_json(&msg)).unwrap()).unwrap();
|
||||
let (rest, ..) = map::to_rest(&msg, &stem, super::layer_budget(message.len()));
|
||||
// A whiteboard's dump shows its native board items as the import makes them.
|
||||
let (rest, ..) = map::to_rest_for(&msg, &stem, super::layer_budget(message.len()), a.canvas.starts_with(super::JAM_HEADER));
|
||||
std::fs::write(format!("{out}/{stem}.rest.json"), serde_json::to_string_pretty(&rest).unwrap()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -797,12 +797,16 @@ impl<'a> Ctx<'a> {
|
||||
/// The `board` field (a FigCraft extension): what the object is on a board. A sticky or shape
|
||||
/// is set at once; anything else, or junk, is ignored with a warning.
|
||||
fn board_item(&mut self, n: &mut Node, b: &'a Value) {
|
||||
// A sticky or shape is a frame holding its layers: on anything else it is ignored.
|
||||
let frame = n.kind.is_frame_like();
|
||||
let item = match text(b, "type") {
|
||||
Some("sticky") => {
|
||||
Some("sticky") if frame => {
|
||||
let author = text(b, "author").unwrap_or("").trim();
|
||||
Some(figcraft_doc::BoardItem::Sticky { author: author.chars().take(64).collect() })
|
||||
Some(figcraft_doc::BoardItem::Sticky { author: author.chars().filter(|c| !c.is_control()).take(64).collect() })
|
||||
}
|
||||
Some("shape") if frame => {
|
||||
text(b, "shape").and_then(figcraft_doc::BoardShape::from_id).map(|shape| figcraft_doc::BoardItem::Shape { shape })
|
||||
}
|
||||
Some("shape") => text(b, "shape").and_then(figcraft_doc::BoardShape::from_id).map(|shape| figcraft_doc::BoardItem::Shape { shape }),
|
||||
_ => None,
|
||||
};
|
||||
match item {
|
||||
|
||||
@@ -97,7 +97,7 @@ fn thousands_of_distinct_style_references_import_in_linear_time() {
|
||||
#[test]
|
||||
fn a_board_field_becomes_the_nodes_board_item() {
|
||||
let frame = json!({"id": "1:1", "name": "Note", "type": "FRAME", "relativeTransform": at(0.0, 0.0), "size": {"x": 200, "y": 200},
|
||||
"board": {"type": "sticky", "author": "A"}});
|
||||
"board": {"type": "sticky", "author": "A\u{7}"}});
|
||||
let (doc, warnings) = import(&file(json!([frame])), &no_images).unwrap();
|
||||
assert_eq!(named(&doc, "Note").board, Some(figcraft_doc::BoardItem::Sticky { author: "A".into() }));
|
||||
assert!(!warnings.iter().any(|w| w.contains("board item")), "{warnings:?}");
|
||||
@@ -112,4 +112,10 @@ fn junk_board_fields_are_ignored_with_a_warning() {
|
||||
assert!(named(&doc, "Junk").board.is_none(), "{junk}");
|
||||
assert!(warnings.iter().any(|w| w.contains("unknown board item on Junk was ignored")), "{junk}: {warnings:?}");
|
||||
}
|
||||
// A sticky is a frame holding its layers: on a rectangle the item is ignored.
|
||||
let rect = json!({"id": "1:2", "name": "Rect", "type": "RECTANGLE", "relativeTransform": at(0.0, 0.0), "size": {"x": 20, "y": 20},
|
||||
"board": {"type": "sticky", "author": "A"}});
|
||||
let (doc, warnings) = import(&file(json!([rect])), &no_images).unwrap();
|
||||
assert!(named(&doc, "Rect").board.is_none());
|
||||
assert!(warnings.iter().any(|w| w.contains("unknown board item on Rect was ignored")), "{warnings:?}");
|
||||
}
|
||||
Reference in new issue
Block a user