我目前将JSON数组反序列化为Vec<String>
,并在应用程序的下游将单个String
转换为SocketAddr
。
我想用serde将其反序列化为Vec<SocketAddr>
。
use serde::Deserialize;
use std::net::SocketAddr;
#[derive(Debug, Deserialize)]
struct Doc {
// It would be nice to have Vec<SocketAddr> instead
hosts: Vec<String>
}
fn main(){
let data = r#"
{"hosts": ["localhost:8000","localhost:8001"]}
"#;
let doc: Doc = serde_json::from_str(data).unwrap();
dbg!(doc);
}
3条答案
按热度按时间31moq8wy1#
我不同意另外两个答案:你完全可以将
"localhost:80"
这样的字符串反序列化为SocketAddr
(Vec of),但是你绝对不应该这样做,让我来解释一下:您的问题是
SocketAddr
只包含一个IP地址+端口,而不是主机名。您可以通过将主机名解析为SockAddr
到ToSocketAddrs
来解决这个问题(然后将结果扁平化,因为一个主机名可以解析为多个地址):Playground
你不应该这样做,因为反序列化应该在序列化中来回,并且是输入字节的纯函数,但是解析地址可能会访问网络。
(做错这些事情是我的一个小毛病,你会在nginx,Kubernetes,Zookeeper,......中找到。)
就我个人而言,出于简单性的原因,我可能会保留
Vec<String>
,但您也可以选择执行一些操作,如反序列化为Vec<(Either<IpAddr, Box<str>>, Option<u16>)>
,以便检查字符串是否为有效地址,但要执行一些操作,如主机名解析和在连接到这些地址时提供默认端口。jei2mxaa2#
Serde支持反序列化到
SocketAddr
,但无法解析您的输入,因为localhost
不是有效的IPv4或IPv6地址。输入需要是一个有效的IPv4或IPv6地址,以便直接反序列化为
SocketAddr
。如果您可以控制输入数据,则可以执行以下操作:下面是输出:
brccelvz3#
您可以直接反序列化为
SocketAddr
,不需要额外的工作:您的问题是
"localhost"
不是有效的SocketAddr
。