gpt4 book ai didi

rust - 必须符合某些语法的字符串的类型

转载 作者:行者123 更新时间:2023-11-29 07:59:20 24 4
gpt4 key购买 nike

我想创建一个行为类似于 String 的“受限”类型,但在构造时验证它是否符合某些语法。例如,我们可能会创建一个 Identifier 类型,其作用类似于 String 但强制所有字符匹配 [a-zA-Z_]

特别是,我想要实现通常的特征(DisplayOrd 等),并且我想要serde::Serializeserde::Deserialize 的行为就像普通的 String 一样,除了我们在反序列化时进行验证。

有没有一种惯用的方法可以做到这一点,还是我必须手动实现所有特征?

最佳答案

惯用的方法是创建一个 newtype围绕 String 并导出可以导出的特征。

For example:

use serde;
use serde_json;

#[derive(
Eq, PartialEq, Ord, PartialOrd,
Debug, Default,
serde::Serialize, serde::Deserialize,
)]
#[serde(transparent)] // to serialize as a string
pub struct Identifier(
#[serde(deserialize_with = "Identifier::deserialize")]
String
);

impl Identifier {
pub fn new(s: String) -> Result<Identifier, &'static str> {
// do some validation
if !s.is_empty() && s.contains('a') {
Ok(Identifier(s))
} else {
Err("Not valid")
}
}

fn deserialize<'de, D>(d: D) -> Result<String, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::Error;
use serde::Deserialize;

let s = String::deserialize(d)?;
Identifier::new(s).map(|i| i.0).map_err(D::Error::custom)
}
}

fn main() {
let a = Identifier::new("aaa".into()).unwrap();
let b: Identifier = serde_json::from_str(r#""faaa""#).unwrap();

println!("{:?}, {:?}", a, b);
println!("{}", a == b);
}

关于rust - 必须符合某些语法的字符串的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55637959/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com