Skip to content

Commit 189a345

Browse files
committed
change Variant serde (de|)serialization
1 parent e68e1c0 commit 189a345

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

rust/src/util.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::cmp::Ordering;
2323
use std::fmt::{self, Display, Formatter};
2424
use std::hash::{Hash, Hasher};
2525
use std::io;
26+
use std::str::FromStr;
2627

2728
use crate::{ReadStruct, VariantName, WriteStruct, STRICT_TYPES_LIB};
2829

@@ -84,13 +85,43 @@ impl Display for Sizing {
8485
}
8586

8687
#[derive(Clone, Eq, Debug)]
87-
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))]
8888
pub struct Variant {
8989
pub name: VariantName,
9090
pub tag: u8,
9191
}
9292
impl_strict_struct!(Variant, STRICT_TYPES_LIB; name, tag);
9393

94+
#[cfg(feature = "serde")]
95+
mod _serde {
96+
use serde_crate::{Deserialize, Deserializer, Serialize, Serializer};
97+
98+
use super::*;
99+
100+
impl Serialize for Variant {
101+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
102+
where S: Serializer {
103+
if serializer.is_human_readable() {
104+
serializer.serialize_str(&self.to_string())
105+
} else {
106+
(&self.name, self.tag).serialize(serializer)
107+
}
108+
}
109+
}
110+
111+
impl<'de> Deserialize<'de> for Variant {
112+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
113+
where D: Deserializer<'de> {
114+
if deserializer.is_human_readable() {
115+
let s = String::deserialize(deserializer)?;
116+
Variant::from_str(&s).map_err(serde::de::Error::custom)
117+
} else {
118+
let (name, tag): (VariantName, u8) = Deserialize::deserialize(deserializer)?;
119+
Ok(Variant { name, tag })
120+
}
121+
}
122+
}
123+
}
124+
94125
impl Variant {
95126
pub fn named(tag: u8, name: VariantName) -> Variant { Variant { name, tag } }
96127

@@ -134,7 +165,22 @@ impl Ord for Variant {
134165

135166
impl Display for Variant {
136167
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
137-
write!(f, "{}", self.name)?;
168+
write!(f, "{}:{}", self.name, self.tag)?;
138169
Ok(())
139170
}
140171
}
172+
173+
impl FromStr for Variant {
174+
type Err = String;
175+
176+
fn from_str(s: &str) -> Result<Self, Self::Err> {
177+
let parts: Vec<&str> = s.split(':').collect();
178+
if parts.len() != 2 {
179+
return Err(format!("Invalid variant format: '{}'. Expected 'name:tag'", s));
180+
}
181+
let name =
182+
VariantName::from_str(parts[0]).map_err(|e| format!("Invalid variant name: {}", e))?;
183+
let tag = parts[1].parse::<u8>().map_err(|e| format!("Invalid variant tag: {}", e))?;
184+
Ok(Variant { name, tag })
185+
}
186+
}

0 commit comments

Comments
 (0)