[00117] Give Size and Color a Lossless CSS String Wire Format - #109
Merged
rorychatt merged 2 commits intoAug 2, 2026
Merged
Conversation
Replace untagged serde derives with custom Serialize/Deserialize implementations that use CSS string format. This makes Size and Color round-trippable and fixes DataTable serialization which was sending bare numbers instead of CSS strings. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Accepted Widget macro implementations from plan 00093 - Removed size_css helper function (now obsolete) - Removed prop(with = size_css) attributes from Layout and Skeleton - Size now serializes itself correctly via custom Serialize impl
rorychatt
deleted the
tendril/00117-GiveSizeAndColorALosslessCSSStringWireFormat
branch
August 2, 2026 10:04
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Changes
Replaced lossy untagged serde serialization with custom Serialize/Deserialize implementations for Size and Color types. Both now serialize to CSS strings ("8px", "50%", "auto", "primary", "#ff0000", "rgba(1, 2, 3, 0.5)") and deserialize back correctly, making them round-trippable. This fixes DataTable and DataTableColumn which were sending bare numbers that clients couldn't interpret.
API Changes
New Public Methods
Size
pub fn parse_css(value: &str) -> Option<Size>— Parse a CSS length string back into a Size variantColor
pub fn to_css(&self) -> String— Render as a CSS color string (wire format)pub fn parse_css(value: &str) -> Option<Color>— Parse a CSS color string back into a Color variantNamedColor
pub fn as_str(&self) -> &'static str— Get the camelCase wire namepub fn parse(value: &str) -> Option<NamedColor>— Parse a camelCase wire name into a variantChanged Serialization Behavior
Size and Color enums now implement custom Serialize/Deserialize traits instead of deriving them with
#[serde(untagged)]. The wire format changes:Before:
Size::Px(8.0)→8.0(indistinguishable from Percent)Size::Percent(8.0)→8.0(indistinguishable from Px)Size::Auto→null(indistinguishable from absent field)Color::Rgba{r:1,g:2,b:3,a:0.5}→{"r":1,"g":2,"b":3,"a":0.5}(different JSON type than Named/Hex)After:
Size::Px(8.0)→"8px"Size::Percent(8.0)→"8%"Size::Auto→"auto"Color::Rgba{r:1,g:2,b:3,a:0.5}→"rgba(1, 2, 3, 0.5)"Named colors and hex colors were already strings and remain unchanged.
Removed Internal Implementation Details
.map(Size::to_css)workaround calls from Container, Image, Layout, and Skeleton widgets' to_json() methods (now redundant since Size serializes itself correctly)cssColor()helper from e2e/app/index.html (Color now always arrives as a string)Files Modified
Core Type Changes:
rusty/src/shared/types.rs— Size custom serialization, +4 tests, -1 obsolete testrusty/src/shared/color.rs— Color custom serialization, NamedColor helpers, +3 testsWidget Updates:
rusty/src/widgets/container.rs— Removed to_css mappingrusty/src/widgets/image.rs— Removed to_css mappingrusty/src/widgets/layout.rs— Removed to_css mappingrusty/src/widgets/skeleton.rs— Removed to_css mappingE2E Renderer:
e2e/app/index.html— Removed cssColor function and call sitesManual Testing
Test the new CSS string serialization:
Run the widget_harness with a container using various Size and Color values:
Open the E2E test page and observe the WebSocket refresh messages in browser DevTools Network tab
Verify Container serialization includes CSS strings:
"width": "200px"(not200.0)"height": "auto"(notnull)"background": "rgba(238, 244, 255, 0.5)"(not an object)Verify Icon serialization includes color as a string:
"color": "primary"or"color": "#ff0000"(always a string)Run the Playwright E2E suite to verify the renderer correctly handles the new format:
Expected: 139 passed (or current count on main)
Test round-tripping:
Run the new unit tests that verify serialization and deserialization:
Both should pass, demonstrating that values survive a to_string/from_str cycle.
Commits
Created using Ivy Tendril.