Hi All,
I'm have some JSON that has some pairs like: "key": "HASS-E,HASS-S"
. I'd like to deserialize this into a struct Hass(Vec<HassType>);
where the comma separated values get deserialized into HassType
s and placed in the Vec
. How can I do this? This is my attempt:
#[derive(Debug, Serialize)]
struct Hass(Vec<HassType>);
#[derive(Debug, Serialize, Deserialize)]
enum HassType {
#[serde(rename = "HASS-A")]
A,
#[serde(rename = "HASS-E")]
E,
#[serde(rename = "HASS-H")]
H,
#[serde(rename = "HASS-S")]
S,
}
impl<'de> Deserialize<'de> for Hass {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct StrVisitor;
impl Visitor<'_> for StrVisitor {
type Value = Vec<HassType>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "expected a &str")
}
fn visit_str<E>(self, text: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
let mut quals = vec![];
for chunk in text.split(',') {
match serde_json::from_str(chunk) {
Ok(qual) => quals.push(qual),
Err(e) => {
println!("{e}");
return Err(de::Error::unknown_variant(
chunk,
&["HASS-A", "HASS-E", "HASS-H", "HASS-S"],
));
}
}
}
Ok(quals)
}
}
let quals = deserializer.deserialize_str(StrVisitor)?;
Ok(Hass(quals))
}
}
However, this code produces an error because "HASS-*" is not valid JSON. Is there something like "deserialize" I can call to go from a string to a T
?
Specifically, once I have access to the input string using visit_str
, how do I deserialize the splits into HassType
s?