feat(shell-core/figma): kind→NodeKind mapper (clipboard JSON one step from real import)
`FigmaClipboardNode::to_node_kind()` maps the 8 most-common Figma
type strings to the closest `crate::document::NodeKind`:
RECTANGLE → Rect
ELLIPSE → Ellipse
LINE → Line
POLYGON / REGULAR_POLY → Polygon
VECTOR → Path
TEXT → Text
FRAME / SECTION → Frame
GROUP → Group
<unknown> → Other(<kind string>)
Unknown kinds round-trip via `NodeKind::Other(...)` so the layer
panel still renders something honest instead of dropping the node.
Future commits add per-kind specialised geometry mappers (fills /
strokes / vectors / text / layout) ported from `pen-figma`.
Tests (2 new):
- 10-case table of every supported Figma kind → expected NodeKind
- Unknown `BOOLEAN_OPERATION` → `Other("BOOLEAN_OPERATION")` round-trip
#9 Figma now ~50% — file kind detection + clipboard JSON walker +
per-child kind + name + NodeKind mapping. Remaining: per-kind
geometry/style mapper functions (the `pen-figma` figma-fill-mapper /
stroke-mapper / text-mapper / vector-decoder / etc port).
Tests total: 245 shell-core (+2). Wasm32 build clean.
This commit is contained in:
parent
d97e1b809d
commit
cf48a006de
|
|
@ -222,6 +222,36 @@ pub struct FigmaClipboardNode {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl FigmaClipboardNode {
|
||||
/// Map this clipboard node's Figma kind string onto the
|
||||
/// closest `NodeKind` in the shell-core document model.
|
||||
/// Unknown kinds round-trip as `NodeKind::Other(kind)` so the
|
||||
/// shell still has a layer-panel entry to display.
|
||||
/// Covers the 8 most-common Figma kinds — the remaining
|
||||
/// specialised types (BOOLEAN_OPERATION, SLICE, COMPONENT,
|
||||
/// INSTANCE, STAR, ...) ship in follow-up commits as the
|
||||
/// converters need them.
|
||||
pub fn to_node_kind(&self) -> crate::document::NodeKind {
|
||||
use crate::document::NodeKind;
|
||||
match self.kind.as_str() {
|
||||
"RECTANGLE" => NodeKind::Rect,
|
||||
"ELLIPSE" => NodeKind::Ellipse,
|
||||
"LINE" => NodeKind::Line,
|
||||
"POLYGON" | "REGULAR_POLYGON" => NodeKind::Polygon,
|
||||
"VECTOR" => NodeKind::Path,
|
||||
"TEXT" => NodeKind::Text,
|
||||
"FRAME" | "GROUP" | "SECTION" => {
|
||||
if self.kind == "GROUP" {
|
||||
NodeKind::Group
|
||||
} else {
|
||||
NodeKind::Frame
|
||||
}
|
||||
}
|
||||
_ => NodeKind::Other(self.kind.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Successful parse result. Carries the file kind, top-level
|
||||
/// children count, and (for clipboard JSON) a minimal-fields
|
||||
/// extraction of each top-level child. Placeholder until the full
|
||||
|
|
@ -327,6 +357,43 @@ mod tests {
|
|||
assert_eq!(parsed.clipboard_nodes[1].name, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn figma_kind_maps_to_node_kind_for_common_types() {
|
||||
use crate::document::NodeKind;
|
||||
let cases = [
|
||||
("RECTANGLE", NodeKind::Rect),
|
||||
("ELLIPSE", NodeKind::Ellipse),
|
||||
("LINE", NodeKind::Line),
|
||||
("POLYGON", NodeKind::Polygon),
|
||||
("REGULAR_POLYGON", NodeKind::Polygon),
|
||||
("VECTOR", NodeKind::Path),
|
||||
("TEXT", NodeKind::Text),
|
||||
("FRAME", NodeKind::Frame),
|
||||
("GROUP", NodeKind::Group),
|
||||
("SECTION", NodeKind::Frame),
|
||||
];
|
||||
for (input, expected) in cases {
|
||||
let n = FigmaClipboardNode {
|
||||
kind: input.into(),
|
||||
name: String::new(),
|
||||
};
|
||||
assert_eq!(n.to_node_kind(), expected, "{input}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn figma_kind_unknown_round_trips_via_other() {
|
||||
use crate::document::NodeKind;
|
||||
let n = FigmaClipboardNode {
|
||||
kind: "BOOLEAN_OPERATION".into(),
|
||||
name: String::new(),
|
||||
};
|
||||
assert_eq!(
|
||||
n.to_node_kind(),
|
||||
NodeKind::Other("BOOLEAN_OPERATION".into())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_fig_returns_unknown_for_random_bytes() {
|
||||
assert_eq!(parse_fig(b"random"), Err(FigParseError::UnknownFormat));
|
||||
|
|
|
|||
Loading…
Reference in a new issue