Remove custom (de)serializers from the DashPattern and BoxCorners TaggedValue variants (#4394)

Replace the DashPattern and BoxCorners custom serde impls with storage-shaped Vec<f64> TaggedValue payloads
This commit is contained in:
Keavon Chambers
2026-08-02 01:00:46 -07:00
committed by Dennis Kobert
parent bf217169f6
commit 8504564f5d
10 changed files with 95 additions and 81 deletions

View File

@@ -124,6 +124,11 @@ pub fn migrate_to_f64_array<'de, D: serde::Deserializer<'de>>(deserializer: D) -
})
}
/// Parses a comma or space separated list of numbers, skipping any pieces that fail to parse.
pub fn parse_f64_list(text: &str) -> Vec<f64> {
text.split([',', ' ']).filter(|piece| !piece.is_empty()).filter_map(|piece| piece.parse::<f64>().ok()).collect()
}
/// Parse a CSS color string (named color, hex, `rgb(...)`, `hsl(...)`, etc.) into a linear-light [`Color`] using the `color` crate's CSS Color 4 parser.
/// Tries the input as-is first (catches CSS named colors like `red`, `rgb(...)`, and well-formed hex like `#abcdef`), then falls back to treating the input as bare hex with length-based expansion to a CSS-parseable form:
/// - 1 char `f` → `#fff` (CSS 3-char shorthand)

View File

@@ -77,21 +77,6 @@ impl BoxCorners {
}
}
// `List<f64>` is a runtime-only wire type, so serialize the corners as their bare values to keep documents stable
#[cfg(feature = "serde")]
impl serde::Serialize for BoxCorners {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.collect_seq(self.0.iter_element_values())
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for BoxCorners {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Self::from(<Vec<f64> as serde::Deserialize>::deserialize(deserializer)?))
}
}
impl From<f64> for BoxCorners {
fn from(value: f64) -> Self {
Self(List::new_from_element(value))
@@ -106,12 +91,7 @@ impl From<Vec<f64>> for BoxCorners {
impl From<&str> for BoxCorners {
fn from(text: &str) -> Self {
Self::from(
text.split([',', ' '])
.filter(|piece| !piece.is_empty())
.filter_map(|piece| piece.parse::<f64>().ok())
.collect::<Vec<f64>>(),
)
Self::from(core_types::misc::parse_f64_list(text))
}
}

View File

@@ -118,18 +118,18 @@ pub enum StrokeCap {
#[default]
#[icon("StrokeCapButt")]
Butt,
#[icon("StrokeCapRound")]
Round,
#[icon("StrokeCapSquare")]
Square,
#[icon("StrokeCapRound")]
Round,
}
impl StrokeCap {
pub fn svg_name(&self) -> &'static str {
match self {
StrokeCap::Butt => "butt",
StrokeCap::Round => "round",
StrokeCap::Square => "square",
StrokeCap::Round => "round",
}
}
}
@@ -218,21 +218,6 @@ impl DashPattern {
}
}
// `List<f64>` is a runtime-only wire type, so serialize the pattern as its bare lengths to keep documents stable
#[cfg(feature = "serde")]
impl serde::Serialize for DashPattern {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.collect_seq(self.0.iter_element_values())
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for DashPattern {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Self::from(<Vec<f64> as serde::Deserialize>::deserialize(deserializer)?))
}
}
impl From<f64> for DashPattern {
fn from(length: f64) -> Self {
Self(List::new_from_element(length))
@@ -247,12 +232,7 @@ impl From<Vec<f64>> for DashPattern {
impl From<&str> for DashPattern {
fn from(text: &str) -> Self {
Self::from(
text.split([',', ' '])
.filter(|piece| !piece.is_empty())
.filter_map(|piece| piece.parse::<f64>().ok())
.collect::<Vec<f64>>(),
)
Self::from(core_types::misc::parse_f64_list(text))
}
}