7 个版本
0.1.6 | 2024年5月14日 |
---|---|
0.1.5 | 2024年1月2日 |
0.1.4 | 2023年12月25日 |
0.1.1 | 2023年8月28日 |
0.0.0 |
|
#249 in 编码
194,379 每月下载量
在 125 个 crate 中使用 (9 直接使用)
58KB
1K SLoC
serde-untagged
此 crate 提供了一个 Serde Visitor
实现,用于反序列化未标记枚举。
[dependencies]
serde-untagged = "0.1"
未标记枚举 Deserialize
实现看起来像这样
use serde::de::{Deserialize, Deserializer};
use serde_untagged::UntaggedEnumVisitor;
impl<'de> Deserialize<'de> for $MyType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
UntaggedEnumVisitor::new()
/*
*
*/
.deserialize(deserializer)
}
}
在 /* ... */
中,我们列出未标记枚举需要支持反序列化的每个类型,提供一个闭包将输入转换为 $MyType。以下类型被支持
- bool
- i8, i16, i32, i64, i128, u8, u16, u32, u64, u128
- f32
- f64
- char
- string
- borrowed_str
- bytes
- borrowed_bytes
- byte_buf
- unit
- seq
- map
示例:字符串或结构体
Cargo 的 http.ssl-version
配置支持从以下两种表示形式反序列化
[http]
ssl-version = "tlsv1.3"
[http]
ssl-version.min = "tlsv1.2"
ssl-version.max = "tlsv1.3"
use serde::de::{Deserialize, Deserializer};
use serde_derive::Deserialize;
use serde_untagged::UntaggedEnumVisitor;
pub enum SslVersionConfig {
Single(String),
Range(SslVersionConfigRange),
}
impl<'de> Deserialize<'de> for SslVersionConfig {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
UntaggedEnumVisitor::new()
.string(|single| Ok(SslVersionConfig::Single(single.to_owned())))
.map(|map| map.deserialize().map(SslVersionConfig::Range))
.deserialize(deserializer)
}
}
#[derive(Deserialize)]
pub struct SslVersionConfigRange {
pub min: Option<String>,
pub max: Option<String>,
}
示例:单元变体或布尔值
Cargo 配置文件中的 LTO 设置支持以下 5 个值 false
,true
,"fat"
,"thin"
,和 "off"
。
[profile.release]
lto = "thin"
use serde::de::{Deserialize, Deserializer, IntoDeserializer};
use serde_derive::Deserialize;
use serde_untagged::UntaggedEnumVisitor;
pub enum LinkTimeOptimization {
Enabled(bool),
Enum(LinkTimeOptimizationString),
}
impl<'de> Deserialize<'de> for LinkTimeOptimization {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
UntaggedEnumVisitor::new()
.bool(|b| Ok(LinkTimeOptimization::Enabled(b)))
.string(|string| {
let de = string.into_deserializer();
LinkTimeOptimizationString::deserialize(de).map(LinkTimeOptimization::Enum)
})
.deserialize(deserializer)
}
}
#[derive(Deserialize)]
#[serde(rename = "lowercase")]
pub enum LinkTimeOptimizationString {
Fat,
Thin,
Off,
}
由于对 Cargo 来说 lto = true
与 lto = "fat"
的意思相同,实际上只有 4 个不同的选项。此类型可以按以下方式实现
use serde::de::{Deserialize, Deserializer, Unexpected};
use serde_untagged::UntaggedEnumVisitor;
pub enum LinkTimeOptimization {
ThinLocal, // false
Fat, // true or "fat"
Thin, // "thin"
Off, // "off"
}
impl<'de> Deserialize<'de> for LinkTimeOptimization {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
UntaggedEnumVisitor::new()
.bool(|b| match b {
false => Ok(LinkTimeOptimization::ThinLocal),
true => Ok(LinkTimeOptimization::Fat),
})
.string(|string| match string {
"fat" => Ok(LinkTimeOptimization::Fat),
"thin" => Ok(LinkTimeOptimization::Thin),
"off" => Ok(LinkTimeOptimization::Off),
_ => Err(serde::de::Error::invalid_value(
Unexpected::Str(string),
&r#""fat" or "thin" or "off""#,
)),
})
.deserialize(deserializer)
}
}
许可证
根据您的选择,此代码受 Apache 许可证 2.0 版 或 MIT 许可证 许可。除非您明确表示,否则您提交的任何贡献,根据 Apache-2.0 许可证的定义,都应按上述方式双重许可,不附加任何额外的条款或条件。
依赖项
~260–495KB
~11K SLoC