Symptom
Unknown attribute names have been errors since the attribute checker was hardened. Unknown attribute shapes are not: a known field given the wrong type passes validation and is discarded at render.
{"type":"text","content":"hello","position":{"x":60,"y":45},"style":{"font-size":24,"color":"#FFF"}}
$ rustmotion validate -f postest.json --strict-attrs
Notice: --strict-attrs is deprecated and does nothing.
Valid scenario: 1 scene(s) in 1 view(s)
position expects the string "absolute" with sibling x/y. Given an object it is silently ignored, the element falls back into flex flow, and nothing anywhere says so.
How it bites
This produced a scene where a cursor and its label were both laid out by flex instead of being anchored, and the cursor's auto_path offsets — which are relative to its own origin — threw it outside its card. The symptom (a stray bar in the wrong place) is a long way from the cause (a field quietly dropped).
Same class: duration as a string, padding as a value the Edges enum does not accept, a number where an enum is expected.
Note on what already works
The checker is not uniformly weak — Edges and the component-level parse do reject bad shapes loudly:
Error: ... invalid component — would be silently dropped at render: unknown field `padding-left`
That is exactly the right behaviour, and the model to extend: the gap is fields consumed outside the typed component parse.
Proposed fix
- Find the fields deserialised leniently outside the typed parse —
position is one — and make their Deserialize reject a shape it cannot use rather than falling back to a default.
- Where a lenient fallback must stay for compatibility, emit the same
would be silently dropped at render diagnostic the component parse already produces, so the wording and the JSON path stay consistent.
- A test per lenient field, asserting that a wrong-typed value is reported rather than defaulted.
Symptom
Unknown attribute names have been errors since the attribute checker was hardened. Unknown attribute shapes are not: a known field given the wrong type passes validation and is discarded at render.
{"type":"text","content":"hello","position":{"x":60,"y":45},"style":{"font-size":24,"color":"#FFF"}}positionexpects the string"absolute"with siblingx/y. Given an object it is silently ignored, the element falls back into flex flow, and nothing anywhere says so.How it bites
This produced a scene where a
cursorand its label were both laid out by flex instead of being anchored, and the cursor'sauto_pathoffsets — which are relative to its own origin — threw it outside its card. The symptom (a stray bar in the wrong place) is a long way from the cause (a field quietly dropped).Same class:
durationas a string,paddingas a value theEdgesenum does not accept, a number where an enum is expected.Note on what already works
The checker is not uniformly weak —
Edgesand the component-level parse do reject bad shapes loudly:That is exactly the right behaviour, and the model to extend: the gap is fields consumed outside the typed component parse.
Proposed fix
positionis one — and make theirDeserializereject a shape it cannot use rather than falling back to a default.would be silently dropped at renderdiagnostic the component parse already produces, so the wording and the JSON path stay consistent.