Skip to content

Commit 563d005

Browse files
committed
change Variant serde (de|)serialization
1 parent e68e1c0 commit 563d005

File tree

1 file changed

+39
-2
lines changed

1 file changed

+39
-2
lines changed

rust/src/util.rs

Lines changed: 39 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,34 @@ 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+
serializer.serialize_str(&self.to_string())
104+
}
105+
}
106+
107+
impl<'de> Deserialize<'de> for Variant {
108+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
109+
where D: Deserializer<'de> {
110+
let s = String::deserialize(deserializer)?;
111+
Variant::from_str(&s).map_err(serde::de::Error::custom)
112+
}
113+
}
114+
}
115+
94116
impl Variant {
95117
pub fn named(tag: u8, name: VariantName) -> Variant { Variant { name, tag } }
96118

@@ -134,7 +156,22 @@ impl Ord for Variant {
134156

135157
impl Display for Variant {
136158
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
137-
write!(f, "{}", self.name)?;
159+
write!(f, "{}:{}", self.name, self.tag)?;
138160
Ok(())
139161
}
140162
}
163+
164+
impl FromStr for Variant {
165+
type Err = String;
166+
167+
fn from_str(s: &str) -> Result<Self, Self::Err> {
168+
let parts: Vec<&str> = s.split(':').collect();
169+
if parts.len() != 2 {
170+
return Err(format!("Invalid variant format: '{}'. Expected 'name:tag'", s));
171+
}
172+
let name =
173+
VariantName::from_str(parts[0]).map_err(|e| format!("Invalid variant name: {}", e))?;
174+
let tag = parts[1].parse::<u8>().map_err(|e| format!("Invalid variant tag: {}", e))?;
175+
Ok(Variant { name, tag })
176+
}
177+
}

0 commit comments

Comments
 (0)