Page MenuHomePhabricator

D12903.id42849.diff
No OneTemporary

D12903.id42849.diff

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

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)

Event Timeline