序列化未实现序列化的外部crate枚举的vec [英] Serialize vec of external crate enum which doesn't implement serialization

查看:115
本文介绍了序列化未实现序列化的外部crate枚举的vec的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用带有未实现序列化的枚举的外部板条箱,并且我想在将包含此枚举的Vec的struct中使用它,并有可能反序列化此结构。基于 serde文档我在下面的代码中创建

I use external crate with enum which does not implement serialization, and I want to use it in struct which will contain Vec of of this enum and have possibility de/serialize this struct. Based on serde documentation I created below code

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");
    }
}

铁锈操场

但我想要的就是包含外部CrateColor Vec的色相结构:

But what I want is to have Hue struct to contain Vec of ExternalCrateColor:

struct Hue {
    #[serde(with = "LocalColor")]
    colors: Vec<ExternalCrateColor>
}

,它不起作用,因为在这种情况下,反序列化要求使用单个ExternalCrateColor。

and it does not works because de/serialization expect in this case single ExternalCrateColor. How to make it work?

推荐答案

我认为您无法使用serde的远程类型功能来完成这项工作,但您可以先定义一个转换来实现:

I don't think you can make this work using the remote-type feature of serde, but you can do it by first defining a conversion:

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,
    }
}

使用这些转换,您可以像这样实现它:

Using these conversions, you can implement it like this:

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>
}

这篇关于序列化未实现序列化的外部crate枚举的vec的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆