序列化未实现序列化的外部板条箱枚举的 vec
Serialize vec of external crate enum which doesn't implement serialization
我将外部板条箱与未实现序列化的枚举一起使用,我想在包含此枚举的 Vec 的结构中使用它,并且有可能 de/serialize 此结构。基于 serde documentation 我创建了以下代码
use serde::{Serialize, Deserialize};
#[derive(Debug, PartialEq, Eq)]
enum ExternalCrateColor {
Red,
Green,
Blue
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(remote = "ExternalCrateColor")]
enum LocalColor {
Red,
Green,
Blue
}
#[derive(Debug, Serialize, Deserialize)]
struct Hue {
#[serde(with = "LocalColor")]
color: ExternalCrateColor
}
fn main() {
let tones = Hue { color: ExternalCrateColor::Blue };
let serialized = serde_json::to_string(&tones).unwrap();
println!("serialized = {}", serialized);
let deserialized: Hue = serde_json::from_str(&serialized).unwrap();
if deserialized.color == ExternalCrateColor::Blue {
println!("Blue tones");
}
}
但我想要的是让 Hue 结构包含 ExternalCrateColor 的 Vec:
struct Hue {
#[serde(with = "LocalColor")]
colors: Vec<ExternalCrateColor>
}
它不起作用,因为 de/serialization 在这种情况下期望单个 ExternalCrateColor。如何让它发挥作用?
我需要检查 serde
的代码库,但我能够通过 hack 使其工作。
use serde::{Serialize, Deserialize};
#[derive(Debug, PartialEq, Eq,)]
enum ExternalCrateColor {
Red,
Green,
Blue
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(remote = "ExternalCrateColor")]
enum LocalColor {
Red,
Green,
Blue
}
#[derive(Debug, Serialize, Deserialize)]
struct Adapter {
#[serde(with = "LocalColor")]
color: ExternalCrateColor
}
#[derive(Debug, Serialize, Deserialize)]
struct Hue {
colors: Vec<Adapter>
}
fn main() {
let adapters = vec![Adapter { color: ExternalCrateColor::Blue }, Adapter {color: ExternalCrateColor::Green}];
let hue = Hue {colors: adapters};
// let tones = Hue { color: ExternalCrateColor::Blue };
// let serialized = serde_json::to_string(&tones).unwrap();
// println!("serialized = {}", serialized);
// let deserialized: Hue = serde_json::from_str(&serialized).unwrap();
// if deserialized.color == ExternalCrateColor::Blue {
// println!("Blue tones");
// }
}
我不认为你可以使用 serde 的远程类型功能来完成这项工作,但你可以通过首先定义一个转换来完成:
fn to_local(color: &ExternalCrateColor) -> LocalColor {
match color {
ExternalCrateColor::Red => LocalColor::Red,
ExternalCrateColor::Green => LocalColor::Green,
ExternalCrateColor::Blue => LocalColor::Blue,
}
}
fn to_external(color: &LocalColor) -> ExternalCrateColor {
match color {
LocalColor::Red => ExternalCrateColor::Red,
LocalColor::Green => ExternalCrateColor::Green,
LocalColor::Blue => ExternalCrateColor::Blue,
}
}
使用这些转换,您可以像这样实现它:
fn color_vec_ser<S: Serializer>(
vec: &Vec<ExternalCrateColor>,
serializer: S
) -> Result<S::Ok, S::Error> {
// First convert the vector into a Vec<LocalColor>.
let vec2: Vec<LocalColor> = vec.iter().map(to_local).collect();
// Instead of serializing Vec<ExternalCrateColor>, we serialize Vec<LocalColor>.
vec2.serialize(serializer)
}
fn color_vec_deser<'de, D: Deserializer<'de>>(
deserializer: D
) -> Result<Vec<ExternalCrateColor>, D::Error> {
// Deserialize as if it was a Vec<LocalColor>.
let vec: Vec<LocalColor> = Deserialize::deserialize(deserializer)?;
// Convert it into an Vec<ExternalCrateColor>
Ok(vec.iter().map(to_external).collect())
}
#[derive(Debug, Serialize, Deserialize)]
struct Hue {
#[serde(serialize_with = "color_vec_ser")]
#[serde(deserialize_with = "color_vec_deser")]
colors: Vec<ExternalCrateColor>
}
我将外部板条箱与未实现序列化的枚举一起使用,我想在包含此枚举的 Vec 的结构中使用它,并且有可能 de/serialize 此结构。基于 serde documentation 我创建了以下代码
use serde::{Serialize, Deserialize};
#[derive(Debug, PartialEq, Eq)]
enum ExternalCrateColor {
Red,
Green,
Blue
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(remote = "ExternalCrateColor")]
enum LocalColor {
Red,
Green,
Blue
}
#[derive(Debug, Serialize, Deserialize)]
struct Hue {
#[serde(with = "LocalColor")]
color: ExternalCrateColor
}
fn main() {
let tones = Hue { color: ExternalCrateColor::Blue };
let serialized = serde_json::to_string(&tones).unwrap();
println!("serialized = {}", serialized);
let deserialized: Hue = serde_json::from_str(&serialized).unwrap();
if deserialized.color == ExternalCrateColor::Blue {
println!("Blue tones");
}
}
但我想要的是让 Hue 结构包含 ExternalCrateColor 的 Vec:
struct Hue {
#[serde(with = "LocalColor")]
colors: Vec<ExternalCrateColor>
}
它不起作用,因为 de/serialization 在这种情况下期望单个 ExternalCrateColor。如何让它发挥作用?
我需要检查 serde
的代码库,但我能够通过 hack 使其工作。
use serde::{Serialize, Deserialize};
#[derive(Debug, PartialEq, Eq,)]
enum ExternalCrateColor {
Red,
Green,
Blue
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(remote = "ExternalCrateColor")]
enum LocalColor {
Red,
Green,
Blue
}
#[derive(Debug, Serialize, Deserialize)]
struct Adapter {
#[serde(with = "LocalColor")]
color: ExternalCrateColor
}
#[derive(Debug, Serialize, Deserialize)]
struct Hue {
colors: Vec<Adapter>
}
fn main() {
let adapters = vec![Adapter { color: ExternalCrateColor::Blue }, Adapter {color: ExternalCrateColor::Green}];
let hue = Hue {colors: adapters};
// let tones = Hue { color: ExternalCrateColor::Blue };
// let serialized = serde_json::to_string(&tones).unwrap();
// println!("serialized = {}", serialized);
// let deserialized: Hue = serde_json::from_str(&serialized).unwrap();
// if deserialized.color == ExternalCrateColor::Blue {
// println!("Blue tones");
// }
}
我不认为你可以使用 serde 的远程类型功能来完成这项工作,但你可以通过首先定义一个转换来完成:
fn to_local(color: &ExternalCrateColor) -> LocalColor {
match color {
ExternalCrateColor::Red => LocalColor::Red,
ExternalCrateColor::Green => LocalColor::Green,
ExternalCrateColor::Blue => LocalColor::Blue,
}
}
fn to_external(color: &LocalColor) -> ExternalCrateColor {
match color {
LocalColor::Red => ExternalCrateColor::Red,
LocalColor::Green => ExternalCrateColor::Green,
LocalColor::Blue => ExternalCrateColor::Blue,
}
}
使用这些转换,您可以像这样实现它:
fn color_vec_ser<S: Serializer>(
vec: &Vec<ExternalCrateColor>,
serializer: S
) -> Result<S::Ok, S::Error> {
// First convert the vector into a Vec<LocalColor>.
let vec2: Vec<LocalColor> = vec.iter().map(to_local).collect();
// Instead of serializing Vec<ExternalCrateColor>, we serialize Vec<LocalColor>.
vec2.serialize(serializer)
}
fn color_vec_deser<'de, D: Deserializer<'de>>(
deserializer: D
) -> Result<Vec<ExternalCrateColor>, D::Error> {
// Deserialize as if it was a Vec<LocalColor>.
let vec: Vec<LocalColor> = Deserialize::deserialize(deserializer)?;
// Convert it into an Vec<ExternalCrateColor>
Ok(vec.iter().map(to_external).collect())
}
#[derive(Debug, Serialize, Deserialize)]
struct Hue {
#[serde(serialize_with = "color_vec_ser")]
#[serde(deserialize_with = "color_vec_deser")]
colors: Vec<ExternalCrateColor>
}