gpt4 book ai didi

rust - 程序宏如何检查Option

转载 作者:行者123 更新时间:2023-12-03 11:47:51 27 4
gpt4 key购买 nike

我正在编写一个派生过程宏,其中所有值都转换为Options。问题在于结构中的任何Option字段都可以包含在这些Option类型中。就其本身而言,在我开始使用serde序列化数据之前,这并不是什么大问题。我希望能够跳过值为None的任何值,但是在某些情况下,它会变成类似于Some(None)Some(CustomOption::None)的值。这两种情况都比简单的None有意义,但我不能只在派生字段上写#[serde(skip_serializing_if = "Option::is_none")]。当然,它们虽然会以JSON格式输出null值。
基本上,我希望能够使用syn库来检查派生字段的内部值的类型是否为Option并将其展平为派生结构中的单数Option<T>而不是Option<Option<T>>类型。我希望Rust在泛型上具有基于类型的模式匹配,但这不是真的。
我可以想到解决这个问题的两种解决方案,但我真的想不到如何实现它们。首先是遍历所有字段并找到Option,然后解开这些选项并重新包装它们,以便它们在外部仅具有一个Option。这种解决方案的一个潜在问题是,在执行计算之后,我可能不得不将它们重新包装在另一个Option中。第二种解决方案是找到Option并相应地修改生成的代码,这样,如果内部选项包含None,整个事情就变成None;基本上只具有一个辅助函数,如果该字段是Option,则输出 bool 值。关于如何实现这些或更好的解决方案的任何想法?
这是一个代码示例:

#[derive(Macro)]
struct X {
a: usize,
b: SomeType<String>,
c: Option<String>,
}
struct GeneratedX {
a: Option<usize>,
b: Option<SomeType<String>>,
c: Option<Option<String>>,
}
使用这样的函数将所有值包装在“选项”中:
pub fn wrap_typ_in_options(&self) -> TokenStream {
// self is a struct with the type Type in it along with some other items.
let typ: syn::Type = self.typ();

// attribute to check if should ignore a field.
if self.should_ignore() {
quote! { Option<#typ> }
} else {
quote! { Option<<#typ as module::Trait>::Type> }
}
}

最佳答案

我按照原始帖子中的第二个想法找到了解决此问题的方法。我使用了这样的函数来判断 token 是否是Option:

let idents_of_path = path
.segments
.iter()
.fold(String::new(), |mut acc, v| {
acc.push_str(&v.ident.to_string());
acc.push(':');
acc
});
vec!["Option:", "std:option:Option:", "core:option:Option:"]
.into_iter()
.find(|s| idents_of_path == *s)
.and_then(|_| path.segments.last())
然后,我添加了一个名为 is_option的新方法,如果 Type::Path是一个选项,该方法将返回一个 bool 值。
pub fn is_option(&self) -> bool {
let typ = self.typ();

let opt = match typ {
Type::Path(typepath) if typepath.qself.is_none() => Some(typepath.path.clone()),
_ => None,
};

if let Some(o) = opt {
check_for_option(&o).is_some()
} else {
false
}
}
我根据此调用的结果修改了生成的代码,其方式与我处理各种属性的方式类似。所有这些对于我的特定用例都应该可以正常工作,因为不会将别名 Option引入该生态系统。有点困惑,但现在可以完成工作。

关于rust - 程序宏如何检查Option <Option <T >>的泛型类型并将其展平为单个Option?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63878327/

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