From 571dedbd2ef8c497649fea1b0eb180bd06e34a7c Mon Sep 17 00:00:00 2001 From: hodasemi Date: Mon, 25 Mar 2024 15:08:39 +0100 Subject: [PATCH] Add custom serde implemenation for color --- Cargo.toml | 4 ++++ src/color.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 355f9bb..b7c531a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,7 @@ reprc_proc_macro = { path = "src/reprc_proc_macro" } # networking serde = { version = "1.0.197", features = ["derive"] } + +[dev-dependencies] +serde_json = { version = "1.0.114" } + diff --git a/src/color.rs b/src/color.rs index 6390ffe..c410468 100644 --- a/src/color.rs +++ b/src/color.rs @@ -3,10 +3,11 @@ use std::ops::MulAssign; use std::str::FromStr; use std::{convert::TryFrom, ops::Mul}; +use serde::de::Visitor; use serde::{Deserialize, Serialize}; /// `TextColor` describes the color of the text -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub enum Color { White, Black, @@ -189,6 +190,46 @@ impl Default for Color { } } +impl Serialize for Color { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&format!("{self}")) + } +} + +impl<'de> Deserialize<'de> for Color { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct ColorVisitor; + + impl<'de> Visitor<'de> for ColorVisitor { + type Value = Color; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("`color`") + } + + fn visit_str(self, value: &str) -> Result + where + E: serde::de::Error, + { + Color::try_from(value).map_err(|_| { + serde::de::Error::invalid_value( + serde::de::Unexpected::Str(value), + &ColorVisitor, + ) + }) + } + } + + deserializer.deserialize_identifier(ColorVisitor) + } +} + #[test] fn simple_color_conversion() { let color = Color::try_from("white").unwrap(); @@ -206,3 +247,13 @@ fn hex_color_conversion() { assert_eq!(string, "#FFFFFF"); } + +#[test] +fn color_serde() { + let color = Color::try_from("#a64b4b").unwrap(); + + let s = serde_json::to_string(&color).unwrap(); + let c = serde_json::from_str(&s).unwrap(); + + assert_eq!(color, c); +}