我需要反序列化以下有效负载,特别是来自JSON对象的aud
字段:
claims: Claims {
aud: One("CBr3zBlrKBbwmxOAM1avZQ=="), // 24 len
// ...
}
[claims::aud
是一个Aud
枚举:
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum Aud {
One(String),
Many(Vec<String>),
}
[当我尝试从String
中获取serde_json::to_string()
时,它返回另外两个字符,即开始和结束字符。
use serde_json::Result;
fn aud_from_json(data: &claims::Aud) -> Result<String> {
let v = serde_json::to_string(&data)?;
Ok(v.to_owned())
}
let aud = aud_from_json(&token_data.claims.aud)?;
log::debug!("aud field: {:?}\t aud field len({})", &aud, &aud.len());
$ aud field: "\"CBr3zBlrKBbwmxOAM1avZQ==\"" aud field len(26)
看来可能会有尾随的转义字符序列化到字符串中。有没有一种方法可以将aud
字段返回为String
,并且在没有多余字符的情况下进行了清理?例如"CBr3zBlrKBbwmxOAM1avZQ=="
您的问题源于对serde
板条箱实际使用的方法的基本误解。特别是to_json()
不会生成JSON fragment。它返回一个完整的,完全有效的可解析JSON文档。
将独立字符串表示为JSON的方式涉及将其用引号引起来,就像您将其作为字段的一部分一样。因此,您的字段包含"CBr3zBlrKBbwmxOAM1avZQ=="
并不奇怪,其中两个其他字符是引号和结尾引号。
您可以通过在playground上进行检查来使自己相信这一点:
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum Aud {
One(String),
Many(Vec<String>),
}
fn aud_from_json(data: &Aud) -> Result<String> {
let v = serde_json::to_string(&data)?;
Ok(v.to_owned())
}
#[test]
fn works() {
let aud = Aud::One("CBr3zBlrKBbwmxOAM1avZQ==".to_string());
let serialized = aud_from_json(&aud).unwrap();
assert_eq!(aud_from_json(&aud).unwrap(), "\"CBr3zBlrKBbwmxOAM1avZQ==\"".to_string());
let deser:Aud = serde_json::from_str(&serialized).unwrap();
assert_eq!(aud, deser);
}
请注意,此单个字符串为足够,以唯一地标识为反序列化提供的enum
的哪个变体,因为参数类型不同。
[如果您还有其他期望,则需要自己实现Deserialize
。有关如何执行此操作的示例很多。
如果您不希望使用引号,那么您实际上根本不应该首先序列化为JSON,因为JSON中未引用的字符串文字在任何地方都无效。
[如果您担心双引号,那纯粹是因为您正在调用Debug
。它们实际上不在String
中,默认情况下Debug
打印用引号引起来的字符串。
[如果我正确理解了您对@SébastienRenauld的回答的回答,则您希望对Aud
实例中包含的字符串进行base-64解码。这可以通过以下方式实现:
let aud = Aud::One("CBr3zBlrKBbwmxOAM1avZQ==".to_string());
if let Aud::One(code) = aud {
let decoded = base64::decode(&code).unwrap();
log::debug!("Decoded: {:?}", decoded);
}
不要在调试模式下打印输出:在格式字符串中使用{}
而不是{:?}
:
log::debug!("aud field: {}\t aud field len({})", &aud, &aud.len());