Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F2762295
D12903.id42849.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
2 KB
Referenced Files
None
Subscribers
None
D12903.id42849.diff
View Options
diff --git a/shared/util_macros/src/lib.rs b/shared/util_macros/src/lib.rs
--- a/shared/util_macros/src/lib.rs
+++ b/shared/util_macros/src/lib.rs
@@ -8,7 +8,7 @@
/// totally ignores the `tag` attribute when deserializing enum variants.
///
/// This derive requires two serde attributes to be present:
-/// `#[serde(tag = "type", remote = "Self")]`
+/// `#[serde(tag = "<<some_tag>>", remote = "Self")]`
///
/// ### Example
/// ```
diff --git a/shared/util_macros/src/tag_aware_deserialize.rs b/shared/util_macros/src/tag_aware_deserialize.rs
--- a/shared/util_macros/src/tag_aware_deserialize.rs
+++ b/shared/util_macros/src/tag_aware_deserialize.rs
@@ -5,6 +5,14 @@
pub fn impl_tag_aware_deserialize_macro(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
+ if !has_serde_remote_self(&ast.attrs) {
+ panic!("{} must have #[serde(remote = \"Self\")] directive", name);
+ }
+
+ let Some(tag_value) = extract_tag_value(&ast.attrs) else {
+ panic!("{} must have #[serde(tag = \"...\")] directive", name);
+ };
+
let gen = quote! {
impl<'de> serde::de::Deserialize<'de> for #name {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
@@ -14,7 +22,7 @@
use serde::de::Error;
let this = serde_json::Value::deserialize(deserializer)?;
- if let Some(found_tag) = this.get("type") {
+ if let Some(found_tag) = this.get(#tag_value) {
if found_tag == stringify!(#name) {
// now we can run _original_ deserialize
return match #name::deserialize(this) {
@@ -39,3 +47,38 @@
};
gen.into()
}
+
+/// Reads the `#[serde(tag = "...")]` value
+fn extract_tag_value(attrs: &[Attribute]) -> Option<String> {
+ let serde_attr = attrs.iter().find(|attr| attr.path.is_ident("serde"))?;
+ if let Ok(Meta::List(meta_list)) = serde_attr.parse_meta() {
+ for nested in meta_list.nested {
+ if let NestedMeta::Meta(Meta::NameValue(name_value)) = nested {
+ if name_value.path.is_ident("tag") {
+ if let Lit::Str(lit_str) = name_value.lit {
+ return Some(lit_str.value());
+ }
+ }
+ }
+ }
+ }
+ None
+}
+
+/// Checks for the `#[serde(remote = "Self")]` attribute
+fn has_serde_remote_self(attrs: &[Attribute]) -> bool {
+ let Some(serde_attr) = attrs.iter().find(|attr| attr.path.is_ident("serde"))
+ else {
+ return false;
+ };
+ if let Ok(Meta::List(meta_list)) = serde_attr.parse_meta() {
+ for nested in meta_list.nested {
+ if let NestedMeta::Meta(Meta::NameValue(name_value)) = nested {
+ if name_value.path.is_ident("remote") {
+ return matches!(name_value.lit, Lit::Str(lit_str) if lit_str.value() == "Self");
+ }
+ }
+ }
+ }
+ false
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Sep 20, 9:23 AM (18 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2147994
Default Alt Text
D12903.id42849.diff (2 KB)
Attached To
Mode
D12903: [util-macros] Improve TagAwareDeserialize to read serde attributes
Attached
Detach File
Event Timeline
Log In to Comment