From d0893f4012636d61904df7dcb30f0abd86c99867 Mon Sep 17 00:00:00 2001 From: Harsha Teja Kanna Date: Mon, 23 Sep 2024 04:21:30 -0400 Subject: [PATCH] Fix serde of table align Closes GH-142. --- src/mdast.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++---- tests/serde.rs | 12 ++++--- 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/src/mdast.rs b/src/mdast.rs index f0ad92ae..d207cd3c 100644 --- a/src/mdast.rs +++ b/src/mdast.rs @@ -33,11 +33,6 @@ pub enum ReferenceKind { /// /// Used to align the contents of table cells within a table. #[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[cfg_attr( - feature = "serde", - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "lowercase") -)] pub enum AlignKind { /// Left alignment. /// @@ -78,10 +73,91 @@ pub enum AlignKind { /// > | | --- | /// ^^^ /// ``` - // To do: this should serialize in serde as `null`. None, } +/// Implement serde according to +#[cfg(feature = "serde")] +impl serde::ser::Serialize for AlignKind { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + match self { + AlignKind::Left => serializer.serialize_unit_variant("AlignKind", 0, "left"), + AlignKind::Right => serializer.serialize_unit_variant("AlignKind", 1, "right"), + AlignKind::Center => serializer.serialize_unit_variant("AlignKind", 2, "center"), + AlignKind::None => serializer.serialize_none(), + } + } +} + +#[cfg(feature = "serde")] +struct AlignKindVisitor; + +#[cfg(feature = "serde")] +impl<'de> serde::de::Visitor<'de> for AlignKindVisitor { + type Value = AlignKind; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("'left', 'right', 'center' or null") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + match v { + "left" => Ok(AlignKind::Left), + "right" => Ok(AlignKind::Right), + "center" => Ok(AlignKind::Center), + &_ => Err(serde::de::Error::invalid_type( + serde::de::Unexpected::Str(v), + &self, + )), + } + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + match v { + b"left" => Ok(AlignKind::Left), + b"right" => Ok(AlignKind::Right), + b"center" => Ok(AlignKind::Center), + &_ => Err(serde::de::Error::invalid_type( + serde::de::Unexpected::Bytes(v), + &self, + )), + } + } + + fn visit_none(self) -> Result + where + E: serde::de::Error, + { + Ok(AlignKind::None) + } + + fn visit_unit(self) -> Result + where + E: serde::de::Error, + { + Ok(AlignKind::None) + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::de::Deserialize<'de> for AlignKind { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + deserializer.deserialize_any(AlignKindVisitor) + } +} + /// Nodes. #[derive(Clone, Eq, PartialEq)] #[cfg_attr( diff --git a/tests/serde.rs b/tests/serde.rs index e10e6926..2edc9acc 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -606,26 +606,30 @@ fn serde_heading() -> Result<(), Error> { fn serde_table() -> Result<(), Error> { // To do: `"none"` should serialize in serde as `null`. assert_serde( - "| a | b |\n| - | -: |\n| 1 | 2 |", + "| a | b | c | d |\n| - | :- | -: | :-: |\n| 1 | 2 | 3 | 4 |", r#"{ "type": "root", "children": [ { "type": "table", - "align": ["none", "right"], + "align": [null, "left", "right", "center"], "children": [ { "type": "tableRow", "children": [ {"type": "tableCell", "children": [{"type": "text", "value": "a"}]}, - {"type": "tableCell", "children": [{"type": "text", "value": "b"}]} + {"type": "tableCell", "children": [{"type": "text", "value": "b"}]}, + {"type": "tableCell", "children": [{"type": "text", "value": "c"}]}, + {"type": "tableCell", "children": [{"type": "text", "value": "d"}]} ] }, { "type": "tableRow", "children": [ {"type": "tableCell","children": [{"type": "text", "value": "1"}]}, - {"type": "tableCell","children": [{"type": "text", "value": "2"}]} + {"type": "tableCell","children": [{"type": "text", "value": "2"}]}, + {"type": "tableCell","children": [{"type": "text", "value": "3"}]}, + {"type": "tableCell","children": [{"type": "text", "value": "4"}]} ] } ]