From 73a0f83438616829db0d0827118426b15d98bcc8 Mon Sep 17 00:00:00 2001 From: Syudagye Date: Sun, 15 Jan 2023 22:00:40 +0100 Subject: [PATCH 01/17] XRBK macro: Changed `hide` attribute to specify the ignored traits --- src/x11/event.rs | 3 ++- xrbk_macro/src/attribute.rs | 6 +++++- xrbk_macro/src/attribute/expansion.rs | 3 +++ xrbk_macro/src/attribute/parsing.rs | 24 ++++++++++++++++++------ xrbk_macro/src/element.rs | 16 ++++++++++++++++ xrbk_macro/src/element/expansion/xrbk.rs | 10 ++++++---- 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/x11/event.rs b/src/x11/event.rs index f3cd7620..6d117c4c 100644 --- a/src/x11/event.rs +++ b/src/x11/event.rs @@ -33,7 +33,7 @@ use xrbk_macro::{derive_xrb, ConstantX11Size, Readable, Writable, X11Size}; extern crate self as xrb; derive_xrb! { - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Hash, PartialEq, Eq, X11Size, Readable, Writable)] /// An [event] generated when a key is pressed. /// /// This [event] is generated for all keys: that includes modifier keys. @@ -47,6 +47,7 @@ derive_xrb! { /// [`KEY_PRESS`]: crate::mask::EventMask::KEY_PRESS pub struct KeyPress: Event(2) { #[sequence] + #[hide(PartialEq)] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// diff --git a/xrbk_macro/src/attribute.rs b/xrbk_macro/src/attribute.rs index c6131de4..2ab8270b 100644 --- a/xrbk_macro/src/attribute.rs +++ b/xrbk_macro/src/attribute.rs @@ -5,7 +5,7 @@ mod expansion; pub mod parsing; -use syn::{token, Path, Token}; +use syn::{punctuated::Punctuated, token, Path, Token}; use crate::Source; @@ -117,6 +117,10 @@ pub struct HideAttribute { /// The attribute path: `hide` for a `HideAttribute`. pub path: Path, + + pub paren_token: token::Paren, + + pub hidden_traits: Punctuated, } /// An attribute which provides the [`ContextualReadable::Context`] for a type diff --git a/xrbk_macro/src/attribute/expansion.rs b/xrbk_macro/src/attribute/expansion.rs index 8f5d28f2..f44852f8 100644 --- a/xrbk_macro/src/attribute/expansion.rs +++ b/xrbk_macro/src/attribute/expansion.rs @@ -69,6 +69,9 @@ impl ToTokens for HideAttribute { // Square brackets surrounding `hide`. self.bracket_token.surround(tokens, |tokens| { self.path.to_tokens(tokens); + self.paren_token.surround(tokens, |tokens| { + self.hidden_traits.to_tokens(tokens); + }) }); } } diff --git a/xrbk_macro/src/attribute/parsing.rs b/xrbk_macro/src/attribute/parsing.rs index c423b9c7..747430dd 100644 --- a/xrbk_macro/src/attribute/parsing.rs +++ b/xrbk_macro/src/attribute/parsing.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use proc_macro2::TokenStream as TokenStream2; -use quote::ToTokens; +use quote::{format_ident, ToTokens}; use syn::{ braced, bracketed, @@ -188,10 +188,16 @@ impl ParseWithContext for ParsedAttributes { )); } + let inner_content; + let paren_token = parenthesized!(inner_content in content); + let hidden_traits = inner_content.parse_terminated(Path::parse)?; + hide_attribute = Some(HideAttribute { hash_token, bracket_token, path, + paren_token, + hidden_traits, }); // Otherwise, if the name was not `context`, `metabyte`, nor // `sequence`, parse the attribute as a normal attribute. @@ -207,11 +213,17 @@ impl ParseWithContext for ParsedAttributes { } } - if let Some(hide_attribute) = &hide_attribute && context_attribute.is_none() { - return Err(syn::Error::new( - hide_attribute.span(), - "hide attributes cannot be used without a context attribute to read the field", - )); + if let Some(hide_attribute) = &hide_attribute + && context_attribute.is_none() + && hide_attribute + .hidden_traits + .iter() + .any(|r#trait| r#trait.is_ident(&format_ident!("Readable"))) + { + return Err(syn::Error::new( + hide_attribute.span(), + "Cannot hide `Readable` without a context attribute to read the field", + )); } Ok(Self { diff --git a/xrbk_macro/src/element.rs b/xrbk_macro/src/element.rs index 32bf828f..841a07cf 100644 --- a/xrbk_macro/src/element.rs +++ b/xrbk_macro/src/element.rs @@ -473,6 +473,13 @@ impl Element { false } } + + pub fn is_ignoring_trait(&self, ident: Ident) -> bool { + if let Element::Field(field) = self { + return field.is_ignoring_trait(ident); + } + false + } } // }}} Field {{{ @@ -602,6 +609,15 @@ impl Field { pub const fn is_error_data(&self) -> bool { self.error_data_attribute.is_some() } + + pub fn is_ignoring_trait(&self, ident: Ident) -> bool { + let Some(hide) = &self.hide_attribute else { + return false; + }; + hide.hidden_traits + .iter() + .any(|r#trait| r#trait.is_ident(&ident)) + } } pub enum FieldId { diff --git a/xrbk_macro/src/element/expansion/xrbk.rs b/xrbk_macro/src/element/expansion/xrbk.rs index 9db3be5c..3f15e57c 100644 --- a/xrbk_macro/src/element/expansion/xrbk.rs +++ b/xrbk_macro/src/element/expansion/xrbk.rs @@ -12,7 +12,7 @@ impl Element { pub fn write_tokens(&self, tokens: &mut TokenStream2, definition_type: DefinitionType) { match self { Self::Field(field) => { - if field.hide_attribute.is_none() { + if !field.is_ignoring_trait(format_ident!("Writable")) { field.write_tokens(tokens) } }, @@ -26,7 +26,7 @@ impl Element { pub fn x11_size_tokens(&self, tokens: &mut TokenStream2, definition_type: DefinitionType) { match self { Self::Field(field) => { - if field.hide_attribute.is_none() { + if !field.is_ignoring_trait(format_ident!("X11Size")) { field.x11_size_tokens(tokens) } }, @@ -40,7 +40,9 @@ impl Element { pub fn read_tokens(&self, tokens: &mut TokenStream2, definition_type: DefinitionType) { match self { Self::Field(field) => { - if field.hide_attribute.is_none() || field.context_attribute.is_some() { + if !field.is_ignoring_trait(format_ident!("Readable")) + || field.context_attribute.is_some() + { field.read_tokens(tokens) } }, @@ -54,7 +56,7 @@ impl Element { pub fn add_x11_size_tokens(&self, tokens: &mut TokenStream2) { match self { Self::Field(field) => { - if field.hide_attribute.is_none() { + if !field.is_ignoring_trait(format_ident!("X11Size")) { field.add_x11_size_tokens(tokens) } }, From 26ae8c9d3545a418d94ae9d6ec877a968a4129f7 Mon Sep 17 00:00:00 2001 From: Syudagye Date: Mon, 16 Jan 2023 01:51:48 +0100 Subject: [PATCH 02/17] XRBK macro: Allowed opt-out of `PartialEq` derive using `#[hide(PartialEq)]` on a field makes it ignore this field when checking equality --- xrbk_macro/src/attribute/parsing.rs | 9 + xrbk_macro/src/definition/expansion.rs | 21 +++ .../src/definition/expansion/partial_eq.rs | 171 ++++++++++++++++++ xrbk_macro/src/element/expansion/xrbk.rs | 21 +++ 4 files changed, 222 insertions(+) create mode 100644 xrbk_macro/src/definition/expansion/partial_eq.rs diff --git a/xrbk_macro/src/attribute/parsing.rs b/xrbk_macro/src/attribute/parsing.rs index 747430dd..2699082c 100644 --- a/xrbk_macro/src/attribute/parsing.rs +++ b/xrbk_macro/src/attribute/parsing.rs @@ -47,6 +47,7 @@ pub struct ParsedItemAttributes { pub derive_writables: Punctuated, pub derive_readables: Punctuated, pub derive_readable_with_contexts: Punctuated, + pub derive_partial_eqs: Punctuated, } impl ParsedItemAttributes { @@ -249,6 +250,7 @@ impl Parse for ParsedItemAttributes { let mut derive_writables = Punctuated::new(); let mut derive_readables = Punctuated::new(); let mut derive_readable_with_contexts = Punctuated::new(); + let mut derive_partial_eqs = Punctuated::new(); while input.peek(Token![#]) && input.peek2(token::Bracket) { let content; @@ -303,6 +305,12 @@ impl Parse for ParsedItemAttributes { if let Some(comma) = comma { derive_readable_with_contexts.push_punct(comma); } + } else if path.is_ident("PartialEq") { + derive_partial_eqs.push_value(path); + + if let Some(comma) = comma { + derive_partial_eqs.push_punct(comma); + } } else { paths.push(path); @@ -348,6 +356,7 @@ impl Parse for ParsedItemAttributes { derive_writables, derive_readables, derive_readable_with_contexts, + derive_partial_eqs, }) } } diff --git a/xrbk_macro/src/definition/expansion.rs b/xrbk_macro/src/definition/expansion.rs index 270cec5a..73d63f4d 100644 --- a/xrbk_macro/src/definition/expansion.rs +++ b/xrbk_macro/src/definition/expansion.rs @@ -3,6 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. mod message_trait; +mod partial_eq; mod readable; mod writable; mod x11_size; @@ -41,6 +42,10 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { r#struct.impl_x11_size(tokens, path); } + + for path in &attrs.derive_partial_eqs { + r#struct.impl_partial_eq(tokens, path); + } }, Self::Enum(r#enum) => { @@ -59,6 +64,10 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { r#enum.impl_x11_size(tokens, path); } + + for path in &attrs.derive_partial_eqs { + r#enum.impl_partial_eq(tokens, path); + } }, Self::Request(request) => { @@ -78,6 +87,10 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { request.impl_x11_size(tokens, path); } + + for path in &attrs.derive_partial_eqs { + request.impl_partial_eq(tokens, path); + } }, Self::Reply(reply) => { @@ -97,6 +110,10 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { reply.impl_x11_size(tokens, path); } + + for path in &attrs.derive_partial_eqs { + reply.impl_partial_eq(tokens, path); + } }, Self::Event(event) => { @@ -116,6 +133,10 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { event.impl_x11_size(tokens, path); } + + for path in &attrs.derive_partial_eqs { + event.impl_partial_eq(tokens, path); + } }, Self::Error(error) => { diff --git a/xrbk_macro/src/definition/expansion/partial_eq.rs b/xrbk_macro/src/definition/expansion/partial_eq.rs new file mode 100644 index 00000000..deb8128e --- /dev/null +++ b/xrbk_macro/src/definition/expansion/partial_eq.rs @@ -0,0 +1,171 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use super::*; +use crate::ext::TsExt; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote_spanned; +use syn::Path; + +impl Struct { + pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { + let ident = &self.ident; + + // TODO: add generic bounds + let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); + + // Expand the tokens to read each element. + let eqs = TokenStream2::with_tokens(|tokens| { + for element in &self.content { + element.partial_eq_tokens(tokens); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + #[automatically_derived] + impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { + fn eq(&self, other: &Self) -> bool { + // Default value which will be compared to all checked fields + true + + // All the fields checks + #eqs + } + } + )); + } +} + +impl Enum { + pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { + let ident = &self.ident; + + // TODO: add generic bounds + let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); + + let arms = TokenStream2::with_tokens(|tokens| { + for variant in &self.variants { + let ident = &variant.ident; + + let pat = TokenStream2::with_tokens(|tokens| { + variant.content.pat_cons_to_tokens(tokens); + }); + + let sizes = TokenStream2::with_tokens(|tokens| { + for element in &variant.content { + element.partial_eq_tokens(tokens); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + Self::#ident #pat => { + // Default value which will be compared to all checked fields + true + + // All the fields checks + #sizes + }, + )); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + #[automatically_derived] + impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { + fn eq(&self, other: &Self) -> bool { + match self { + #arms + } + } + } + )); + } +} + +impl Request { + pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { + let ident = &self.ident; + + // TODO: add generic bounds + let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); + + // Expand the tokens to read each element. + let eqs = TokenStream2::with_tokens(|tokens| { + for element in &self.content { + element.partial_eq_tokens(tokens); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + #[automatically_derived] + impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { + fn eq(&self, other: &Self) -> bool { + // Default value which will be compared to all checked fields + true + + // All the fields checks + #eqs + } + } + )); + } +} + +impl Reply { + pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { + let ident = &self.ident; + + // TODO: add generic bounds + let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); + + // Expand the tokens to read each element. + let eqs = TokenStream2::with_tokens(|tokens| { + for element in &self.content { + element.partial_eq_tokens(tokens); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + #[automatically_derived] + impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { + fn eq(&self, other: &Self) -> bool { + // Default value which will be compared to all checked fields + true + + // All the fields checks + #eqs + } + } + )); + } +} + +impl Event { + pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { + let ident = &self.ident; + + // TODO: add generic bounds + let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); + + // Expand the tokens to read each element. + let eqs = TokenStream2::with_tokens(|tokens| { + for element in &self.content { + element.partial_eq_tokens(tokens); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + #[automatically_derived] + impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { + fn eq(&self, other: &Self) -> bool { + // Default value which will be compared to all checked fields + true + + // All the fields checks + #eqs + } + } + )); + } +} diff --git a/xrbk_macro/src/element/expansion/xrbk.rs b/xrbk_macro/src/element/expansion/xrbk.rs index 3f15e57c..642967d1 100644 --- a/xrbk_macro/src/element/expansion/xrbk.rs +++ b/xrbk_macro/src/element/expansion/xrbk.rs @@ -66,6 +66,17 @@ impl Element { Self::ArrayUnused(unused) => unused.add_x11_size_tokens(tokens), } } + + pub fn partial_eq_tokens(&self, tokens: &mut TokenStream2) { + match self { + Self::Field(field) => { + if !field.is_ignoring_trait(format_ident!("PartialEq")) { + field.add_partial_eq_tokens(tokens) + } + }, + _ => (), + } + } } // Field {{{ @@ -147,6 +158,16 @@ impl Field { ) }); } + + pub fn add_partial_eq_tokens(&self, tokens: &mut TokenStream2) { + tokens.append_tokens({ + let ident = &self.id; + + quote_spanned!(self.span()=> + && self.#ident == other.#ident + ) + }); + } } // }}} Let {{{ From c5f44fd3b67a534a886918599988ff8793a8904f Mon Sep 17 00:00:00 2001 From: Syudagye Date: Mon, 16 Jan 2023 02:04:01 +0100 Subject: [PATCH 03/17] XRBK macro: Cleaned repeated code --- .../src/definition/expansion/partial_eq.rs | 150 +++++------------- 1 file changed, 36 insertions(+), 114 deletions(-) diff --git a/xrbk_macro/src/definition/expansion/partial_eq.rs b/xrbk_macro/src/definition/expansion/partial_eq.rs index deb8128e..05c52362 100644 --- a/xrbk_macro/src/definition/expansion/partial_eq.rs +++ b/xrbk_macro/src/definition/expansion/partial_eq.rs @@ -8,35 +8,44 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote_spanned; use syn::Path; -impl Struct { - pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { - let ident = &self.ident; - - // TODO: add generic bounds - let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); - - // Expand the tokens to read each element. - let eqs = TokenStream2::with_tokens(|tokens| { - for element in &self.content { - element.partial_eq_tokens(tokens); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - #[automatically_derived] - impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { - fn eq(&self, other: &Self) -> bool { - // Default value which will be compared to all checked fields - true - - // All the fields checks - #eqs - } - } - )); - } +macro_rules! structlike_impl_partial_eq { + ($def:path) => { + impl $def { + pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { + let ident = &self.ident; + + // TODO: add generic bounds + let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); + + // Expand the tokens to read each element. + let eqs = TokenStream2::with_tokens(|tokens| { + for element in &self.content { + element.partial_eq_tokens(tokens); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + #[automatically_derived] + impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { + fn eq(&self, other: &Self) -> bool { + // Default value which will be compared to all checked fields + true + + // All the fields checks + #eqs + } + } + )); + } + } + }; } +structlike_impl_partial_eq!(Struct); +structlike_impl_partial_eq!(Request); +structlike_impl_partial_eq!(Reply); +structlike_impl_partial_eq!(Event); + impl Enum { pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { let ident = &self.ident; @@ -82,90 +91,3 @@ impl Enum { )); } } - -impl Request { - pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { - let ident = &self.ident; - - // TODO: add generic bounds - let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); - - // Expand the tokens to read each element. - let eqs = TokenStream2::with_tokens(|tokens| { - for element in &self.content { - element.partial_eq_tokens(tokens); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - #[automatically_derived] - impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { - fn eq(&self, other: &Self) -> bool { - // Default value which will be compared to all checked fields - true - - // All the fields checks - #eqs - } - } - )); - } -} - -impl Reply { - pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { - let ident = &self.ident; - - // TODO: add generic bounds - let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); - - // Expand the tokens to read each element. - let eqs = TokenStream2::with_tokens(|tokens| { - for element in &self.content { - element.partial_eq_tokens(tokens); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - #[automatically_derived] - impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { - fn eq(&self, other: &Self) -> bool { - // Default value which will be compared to all checked fields - true - - // All the fields checks - #eqs - } - } - )); - } -} - -impl Event { - pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { - let ident = &self.ident; - - // TODO: add generic bounds - let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); - - // Expand the tokens to read each element. - let eqs = TokenStream2::with_tokens(|tokens| { - for element in &self.content { - element.partial_eq_tokens(tokens); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - #[automatically_derived] - impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { - fn eq(&self, other: &Self) -> bool { - // Default value which will be compared to all checked fields - true - - // All the fields checks - #eqs - } - } - )); - } -} From af574db2b77d2e1dc49dacf26919ae30e1bcc6b4 Mon Sep 17 00:00:00 2001 From: Syudagye Date: Mon, 16 Jan 2023 13:51:39 +0100 Subject: [PATCH 04/17] XRBK macro: Allowed opt-out of `Hash` derive --- src/x11/event.rs | 2 +- xrbk_macro/src/attribute/parsing.rs | 9 +++ xrbk_macro/src/definition/expansion.rs | 22 +++++- .../expansion/{partial_eq.rs => derives.rs} | 69 ++++++++++++++++++- xrbk_macro/src/element/expansion/xrbk.rs | 21 ++++++ 5 files changed, 119 insertions(+), 4 deletions(-) rename xrbk_macro/src/definition/expansion/{partial_eq.rs => derives.rs} (56%) diff --git a/src/x11/event.rs b/src/x11/event.rs index 6d117c4c..a565b9d9 100644 --- a/src/x11/event.rs +++ b/src/x11/event.rs @@ -47,7 +47,7 @@ derive_xrb! { /// [`KEY_PRESS`]: crate::mask::EventMask::KEY_PRESS pub struct KeyPress: Event(2) { #[sequence] - #[hide(PartialEq)] + #[hide(PartialEq, Hash)] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// diff --git a/xrbk_macro/src/attribute/parsing.rs b/xrbk_macro/src/attribute/parsing.rs index 2699082c..6e64bf32 100644 --- a/xrbk_macro/src/attribute/parsing.rs +++ b/xrbk_macro/src/attribute/parsing.rs @@ -48,6 +48,7 @@ pub struct ParsedItemAttributes { pub derive_readables: Punctuated, pub derive_readable_with_contexts: Punctuated, pub derive_partial_eqs: Punctuated, + pub derive_hashes: Punctuated, } impl ParsedItemAttributes { @@ -251,6 +252,7 @@ impl Parse for ParsedItemAttributes { let mut derive_readables = Punctuated::new(); let mut derive_readable_with_contexts = Punctuated::new(); let mut derive_partial_eqs = Punctuated::new(); + let mut derive_hashes = Punctuated::new(); while input.peek(Token![#]) && input.peek2(token::Bracket) { let content; @@ -311,6 +313,12 @@ impl Parse for ParsedItemAttributes { if let Some(comma) = comma { derive_partial_eqs.push_punct(comma); } + } else if path.is_ident("Hash") { + derive_hashes.push_value(path); + + if let Some(comma) = comma { + derive_hashes.push_punct(comma); + } } else { paths.push(path); @@ -357,6 +365,7 @@ impl Parse for ParsedItemAttributes { derive_readables, derive_readable_with_contexts, derive_partial_eqs, + derive_hashes, }) } } diff --git a/xrbk_macro/src/definition/expansion.rs b/xrbk_macro/src/definition/expansion.rs index 73d63f4d..c88358fa 100644 --- a/xrbk_macro/src/definition/expansion.rs +++ b/xrbk_macro/src/definition/expansion.rs @@ -3,7 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. mod message_trait; -mod partial_eq; +mod derives; mod readable; mod writable; mod x11_size; @@ -46,6 +46,10 @@ impl ToTokens for Definition { for path in &attrs.derive_partial_eqs { r#struct.impl_partial_eq(tokens, path); } + + for path in &attrs.derive_hashes { + r#struct.impl_hash(tokens, path); + } }, Self::Enum(r#enum) => { @@ -68,6 +72,10 @@ impl ToTokens for Definition { for path in &attrs.derive_partial_eqs { r#enum.impl_partial_eq(tokens, path); } + + for path in &attrs.derive_hashes { + r#enum.impl_hash(tokens, path); + } }, Self::Request(request) => { @@ -91,6 +99,10 @@ impl ToTokens for Definition { for path in &attrs.derive_partial_eqs { request.impl_partial_eq(tokens, path); } + + for path in &attrs.derive_hashes { + request.impl_hash(tokens, path); + } }, Self::Reply(reply) => { @@ -114,6 +126,10 @@ impl ToTokens for Definition { for path in &attrs.derive_partial_eqs { reply.impl_partial_eq(tokens, path); } + + for path in &attrs.derive_hashes { + reply.impl_hash(tokens, path); + } }, Self::Event(event) => { @@ -137,6 +153,10 @@ impl ToTokens for Definition { for path in &attrs.derive_partial_eqs { event.impl_partial_eq(tokens, path); } + + for path in &attrs.derive_hashes { + event.impl_hash(tokens, path); + } }, Self::Error(error) => { diff --git a/xrbk_macro/src/definition/expansion/partial_eq.rs b/xrbk_macro/src/definition/expansion/derives.rs similarity index 56% rename from xrbk_macro/src/definition/expansion/partial_eq.rs rename to xrbk_macro/src/definition/expansion/derives.rs index 05c52362..f73aef6e 100644 --- a/xrbk_macro/src/definition/expansion/partial_eq.rs +++ b/xrbk_macro/src/definition/expansion/derives.rs @@ -37,6 +37,30 @@ macro_rules! structlike_impl_partial_eq { } )); } + + pub fn impl_hash(&self, tokens: &mut TokenStream2, trait_path: &Path) { + let ident = &self.ident; + + // TODO: add generic bounds + let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); + + // Expand the tokens to read each element. + let hashes = TokenStream2::with_tokens(|tokens| { + for element in &self.content { + element.hash_tokens(tokens); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + #[automatically_derived] + impl #impl_generics ::core::hash::Hash for #ident #type_generics #where_clause { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + // All the hashes for all fiels + #hashes + } + } + )); + } } }; } @@ -61,7 +85,7 @@ impl Enum { variant.content.pat_cons_to_tokens(tokens); }); - let sizes = TokenStream2::with_tokens(|tokens| { + let eqs = TokenStream2::with_tokens(|tokens| { for element in &variant.content { element.partial_eq_tokens(tokens); } @@ -73,7 +97,7 @@ impl Enum { true // All the fields checks - #sizes + #eqs }, )); } @@ -90,4 +114,45 @@ impl Enum { } )); } + + pub fn impl_hash(&self, tokens: &mut TokenStream2, trait_path: &Path) { + let ident = &self.ident; + + // TODO: add generic bounds + let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); + + let arms = TokenStream2::with_tokens(|tokens| { + for variant in &self.variants { + let ident = &variant.ident; + + let pat = TokenStream2::with_tokens(|tokens| { + variant.content.pat_cons_to_tokens(tokens); + }); + + let hashes = TokenStream2::with_tokens(|tokens| { + for element in &variant.content { + element.hash_tokens(tokens); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + Self::#ident #pat => { + // All the hashes for all fiels + #hashes + }, + )); + } + }); + + tokens.append_tokens(quote_spanned!(trait_path.span()=> + #[automatically_derived] + impl #impl_generics ::core::hash::Hash for #ident #type_generics #where_clause { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + match self { + #arms + } + } + } + )); + } } diff --git a/xrbk_macro/src/element/expansion/xrbk.rs b/xrbk_macro/src/element/expansion/xrbk.rs index 642967d1..ceda08d4 100644 --- a/xrbk_macro/src/element/expansion/xrbk.rs +++ b/xrbk_macro/src/element/expansion/xrbk.rs @@ -77,6 +77,17 @@ impl Element { _ => (), } } + + pub fn hash_tokens(&self, tokens: &mut TokenStream2) { + match self { + Self::Field(field) => { + if !field.is_ignoring_trait(format_ident!("Hash")) { + field.add_hash_tokens(tokens) + } + }, + _ => (), + } + } } // Field {{{ @@ -168,6 +179,16 @@ impl Field { ) }); } + + pub fn add_hash_tokens(&self, tokens: &mut TokenStream2) { + tokens.append_tokens({ + let ident = &self.id; + + quote_spanned!(self.span()=> + ::core::hash::Hash::hash(&self.#ident, state); + ) + }); + } } // }}} Let {{{ From 7ee143441eb540fad4099647c9f3b15ad9f130d9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 16 Jan 2023 12:54:00 +0000 Subject: [PATCH 05/17] [CI505] formatted code with rustfmt --- xrbk_macro/src/definition/expansion/derives.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xrbk_macro/src/definition/expansion/derives.rs b/xrbk_macro/src/definition/expansion/derives.rs index f73aef6e..71f0ad3d 100644 --- a/xrbk_macro/src/definition/expansion/derives.rs +++ b/xrbk_macro/src/definition/expansion/derives.rs @@ -146,8 +146,8 @@ impl Enum { tokens.append_tokens(quote_spanned!(trait_path.span()=> #[automatically_derived] - impl #impl_generics ::core::hash::Hash for #ident #type_generics #where_clause { - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + impl #impl_generics ::core::hash::Hash for #ident #type_generics #where_clause { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { match self { #arms } From bfad1745c4d2762ec8e8b529dd251689e8cd9a6e Mon Sep 17 00:00:00 2001 From: Syudagye Date: Mon, 16 Jan 2023 14:29:48 +0100 Subject: [PATCH 06/17] XRBK macro: Updated documentation for `hide` attribute --- xrbk_macro/src/attribute.rs | 20 ++++++++++++++++++-- xrbk_macro/src/element.rs | 7 ++++++- xrbk_macro/src/lib.rs | 22 ++++++++++++++++++++-- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/xrbk_macro/src/attribute.rs b/xrbk_macro/src/attribute.rs index 2ab8270b..0f5e4341 100644 --- a/xrbk_macro/src/attribute.rs +++ b/xrbk_macro/src/attribute.rs @@ -102,11 +102,24 @@ pub struct ErrorDataAttribute { } /// An attribute which indicates that a [`Field`] should not be taken into -/// consideration when implementing XRBK traits. +/// consideration when implementing traits. /// /// > **Syntax**\ /// > _HideAttribute_ :\ -/// >    `#` `[` `hide` `]` +/// >    `#` `[` `hide` `(` _HiddenTraits_ `)` `]` +/// > +/// > _HiddenTraits_ :\ +/// >    _HiddenTrait_[^hidden-traits] ( `,` _HiddenTrait_[^hidden-traits] )\* +/// > +/// > _HiddenTrait_ :\ +/// >       `Readable` \ +/// >    | `Writable` \ +/// >    | `X11Size` \ +/// >    | `PartialEq` \ +/// >    | `Hash` \ +/// > +/// > [^hidden-traits]: *HideAttribute*s may only specify traits listed in *HiddenTraits*, any +/// > other traits will have no effects. /// /// [`Field`]: crate::element::Field pub struct HideAttribute { @@ -118,8 +131,11 @@ pub struct HideAttribute { /// The attribute path: `hide` for a `HideAttribute`. pub path: Path, + /// A pair of square brackets (`(` and `)`) surrounding the `hidden_traits`. pub paren_token: token::Paren, + /// A list of traits which will ingore this field on their implementations. + /// It uses the same style has the derive macro. pub hidden_traits: Punctuated, } diff --git a/xrbk_macro/src/element.rs b/xrbk_macro/src/element.rs index 841a07cf..aa3094d3 100644 --- a/xrbk_macro/src/element.rs +++ b/xrbk_macro/src/element.rs @@ -474,6 +474,8 @@ impl Element { } } + /// Whether this `Element` has an `ignore` attribute that contains the trait specified by + /// `ident`. pub fn is_ignoring_trait(&self, ident: Ident) -> bool { if let Element::Field(field) = self { return field.is_ignoring_trait(ident); @@ -500,7 +502,7 @@ impl Element { /// > /// > _FieldAttribute_ :\ /// >    [_OuterAttribute_] | [_ContextAttribute_] | -/// > [_MetabyteAttribute_] | [_SequenceAttribute_] +/// > [_MetabyteAttribute_] | [_SequenceAttribute_] | [_HideAttribute_] /// > /// > [_Visibility_]: https://doc.rust-lang.org/reference/visibility-and-privacy.html /// > [IDENTIFIER]: https://doc.rust-lang.org/reference/identifiers.html @@ -510,6 +512,7 @@ impl Element { /// > [_ContextAttribute_]: ContextAttribute /// > [_MetabyteAttribute_]: MetabyteAttribute /// > [_SequenceAttribute_]: SequenceAttribute +/// > [_HideAttribute_]: HideAttribute pub struct Field { /// Attributes associated with the `Field`. pub attributes: Vec, @@ -610,6 +613,8 @@ impl Field { self.error_data_attribute.is_some() } + /// Whether this `Element` has an `ignore` attribute that contains the trait specified by + /// `ident`. pub fn is_ignoring_trait(&self, ident: Ident) -> bool { let Some(hide) = &self.hide_attribute else { return false; diff --git a/xrbk_macro/src/lib.rs b/xrbk_macro/src/lib.rs index ea2c58f1..fab64efc 100644 --- a/xrbk_macro/src/lib.rs +++ b/xrbk_macro/src/lib.rs @@ -303,14 +303,16 @@ pub fn derive_constant_x11_size(item: TokenStream) -> TokenStream { /// >    ( [_OuterAttribute_]\ /// >    | _ContextAttribute_[^attr-once]\ /// >    | _MetabyteAttribute_[^attr-once]\ -/// >    | _SequenceAttribute_[^attr-once][^sequence] )\*\ +/// >    | _SequenceAttribute_[^attr-once][^sequence]\ +/// >    | _HideAttribute_[^attr-once] )\*\ /// >    [_Visibility_]? [IDENTIFIER] `:` [_Type_] /// > /// > _UnnamedField_ :\ /// >    ( [_OuterAttribute_]\ /// >    | _ContextAttribute_[^attr-once]\ /// >    | _MetabyteAttribute_[^attr-once]\ -/// >    | _SequenceAttribute_[^attr-once][^sequence] )\*\ +/// >    | _SequenceAttribute_[^attr-once][^sequence]\ +/// >    | _HideAttribute_[^attr-once] )\*\ /// >    [_Visibility_]? [_Type_] /// > /// > _LetElement_ :\ @@ -349,6 +351,22 @@ pub fn derive_constant_x11_size(item: TokenStream) -> TokenStream { /// > _SequenceAttribute_ :\ /// >    `#` `[` `sequence` `]` /// > +/// > _HideAttribute_ :\ +/// >    `#` `[` `hide` `(` _HiddenTraits_ `)` `]` +/// > +/// > _HiddenTraits_ :\ +/// >    _HiddenTrait_[^hidden-traits] ( `,` _HiddenTrait_[^hidden-traits] )\* +/// > +/// > _HiddenTrait_ :\ +/// >       `Readable` \ +/// >    | `Writable` \ +/// >    | `X11Size` \ +/// >    | `PartialEq` \ +/// >    | `Hash` \ +/// > +/// > [^hidden-traits]: *HideAttribute*s may only specify traits listed in *HiddenTraits*, any +/// > other traits will have no effects. +/// > /// > _Source_ :\ /// >    ( _SourceArgs_ `=>` )? [_Expression_] /// > From 67b886078afa512a7cbc2b97952dd9abe6330a1e Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 16 Jan 2023 13:31:46 +0000 Subject: [PATCH 07/17] [CI506] formatted code with rustfmt --- xrbk_macro/src/attribute.rs | 6 ++++-- xrbk_macro/src/element.rs | 8 ++++---- xrbk_macro/src/lib.rs | 6 ++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/xrbk_macro/src/attribute.rs b/xrbk_macro/src/attribute.rs index 0f5e4341..952199dd 100644 --- a/xrbk_macro/src/attribute.rs +++ b/xrbk_macro/src/attribute.rs @@ -109,7 +109,8 @@ pub struct ErrorDataAttribute { /// >    `#` `[` `hide` `(` _HiddenTraits_ `)` `]` /// > /// > _HiddenTraits_ :\ -/// >    _HiddenTrait_[^hidden-traits] ( `,` _HiddenTrait_[^hidden-traits] )\* +/// >    _HiddenTrait_[^hidden-traits] ( `,` +/// > _HiddenTrait_[^hidden-traits] )\* /// > /// > _HiddenTrait_ :\ /// >       `Readable` \ @@ -118,7 +119,8 @@ pub struct ErrorDataAttribute { /// >    | `PartialEq` \ /// >    | `Hash` \ /// > -/// > [^hidden-traits]: *HideAttribute*s may only specify traits listed in *HiddenTraits*, any +/// > [^hidden-traits]: *HideAttribute*s may only specify traits listed in +/// > *HiddenTraits*, any /// > other traits will have no effects. /// /// [`Field`]: crate::element::Field diff --git a/xrbk_macro/src/element.rs b/xrbk_macro/src/element.rs index aa3094d3..c6d60513 100644 --- a/xrbk_macro/src/element.rs +++ b/xrbk_macro/src/element.rs @@ -474,8 +474,8 @@ impl Element { } } - /// Whether this `Element` has an `ignore` attribute that contains the trait specified by - /// `ident`. + /// Whether this `Element` has an `ignore` attribute that contains the trait + /// specified by `ident`. pub fn is_ignoring_trait(&self, ident: Ident) -> bool { if let Element::Field(field) = self { return field.is_ignoring_trait(ident); @@ -613,8 +613,8 @@ impl Field { self.error_data_attribute.is_some() } - /// Whether this `Element` has an `ignore` attribute that contains the trait specified by - /// `ident`. + /// Whether this `Element` has an `ignore` attribute that contains the trait + /// specified by `ident`. pub fn is_ignoring_trait(&self, ident: Ident) -> bool { let Some(hide) = &self.hide_attribute else { return false; diff --git a/xrbk_macro/src/lib.rs b/xrbk_macro/src/lib.rs index fab64efc..20434801 100644 --- a/xrbk_macro/src/lib.rs +++ b/xrbk_macro/src/lib.rs @@ -355,7 +355,8 @@ pub fn derive_constant_x11_size(item: TokenStream) -> TokenStream { /// >    `#` `[` `hide` `(` _HiddenTraits_ `)` `]` /// > /// > _HiddenTraits_ :\ -/// >    _HiddenTrait_[^hidden-traits] ( `,` _HiddenTrait_[^hidden-traits] )\* +/// >    _HiddenTrait_[^hidden-traits] ( `,` +/// > _HiddenTrait_[^hidden-traits] )\* /// > /// > _HiddenTrait_ :\ /// >       `Readable` \ @@ -364,7 +365,8 @@ pub fn derive_constant_x11_size(item: TokenStream) -> TokenStream { /// >    | `PartialEq` \ /// >    | `Hash` \ /// > -/// > [^hidden-traits]: *HideAttribute*s may only specify traits listed in *HiddenTraits*, any +/// > [^hidden-traits]: *HideAttribute*s may only specify traits listed in +/// > *HiddenTraits*, any /// > other traits will have no effects. /// > /// > _Source_ :\ From c8b8e0cb648f650cee8028efebd874a694cd8063 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 16 Jan 2023 15:02:15 +0000 Subject: [PATCH 08/17] [CI507] formatted code with rustfmt --- xrbk_macro/src/definition/expansion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrbk_macro/src/definition/expansion.rs b/xrbk_macro/src/definition/expansion.rs index c88358fa..bfeafab8 100644 --- a/xrbk_macro/src/definition/expansion.rs +++ b/xrbk_macro/src/definition/expansion.rs @@ -2,8 +2,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -mod message_trait; mod derives; +mod message_trait; mod readable; mod writable; mod x11_size; From b74fd1806a154b9fa75685e15f7883ce265101cd Mon Sep 17 00:00:00 2001 From: Syudagye Date: Mon, 16 Jan 2023 16:14:55 +0100 Subject: [PATCH 09/17] XRBK macro: Fixed clippy errors --- .../src/definition/expansion/derives.rs | 5 +++-- xrbk_macro/src/element/expansion/xrbk.rs | 22 +++++++------------ 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/xrbk_macro/src/definition/expansion/derives.rs b/xrbk_macro/src/definition/expansion/derives.rs index 71f0ad3d..84ad379d 100644 --- a/xrbk_macro/src/definition/expansion/derives.rs +++ b/xrbk_macro/src/definition/expansion/derives.rs @@ -27,6 +27,7 @@ macro_rules! structlike_impl_partial_eq { tokens.append_tokens(quote_spanned!(trait_path.span()=> #[automatically_derived] impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { + #[allow(clippy::nonminimal_bool)] fn eq(&self, other: &Self) -> bool { // Default value which will be compared to all checked fields true @@ -54,7 +55,7 @@ macro_rules! structlike_impl_partial_eq { tokens.append_tokens(quote_spanned!(trait_path.span()=> #[automatically_derived] impl #impl_generics ::core::hash::Hash for #ident #type_generics #where_clause { - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { // All the hashes for all fiels #hashes } @@ -147,7 +148,7 @@ impl Enum { tokens.append_tokens(quote_spanned!(trait_path.span()=> #[automatically_derived] impl #impl_generics ::core::hash::Hash for #ident #type_generics #where_clause { - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { match self { #arms } diff --git a/xrbk_macro/src/element/expansion/xrbk.rs b/xrbk_macro/src/element/expansion/xrbk.rs index ceda08d4..619095e3 100644 --- a/xrbk_macro/src/element/expansion/xrbk.rs +++ b/xrbk_macro/src/element/expansion/xrbk.rs @@ -68,24 +68,18 @@ impl Element { } pub fn partial_eq_tokens(&self, tokens: &mut TokenStream2) { - match self { - Self::Field(field) => { - if !field.is_ignoring_trait(format_ident!("PartialEq")) { - field.add_partial_eq_tokens(tokens) - } - }, - _ => (), + if let Self::Field(field) = self { + if !field.is_ignoring_trait(format_ident!("PartialEq")) { + field.add_partial_eq_tokens(tokens) + } } } pub fn hash_tokens(&self, tokens: &mut TokenStream2) { - match self { - Self::Field(field) => { - if !field.is_ignoring_trait(format_ident!("Hash")) { - field.add_hash_tokens(tokens) - } - }, - _ => (), + if let Self::Field(field) = self { + if !field.is_ignoring_trait(format_ident!("Hash")) { + field.add_hash_tokens(tokens) + } } } } From c0b38528ea8309ca659d0fc80db520096c7e6b7a Mon Sep 17 00:00:00 2001 From: Antikyth <104020300+Antikyth@users.noreply.github.com> Date: Mon, 16 Jan 2023 17:09:54 +0000 Subject: [PATCH 10/17] Use `&str` for `is_ignoring_trait`, rather than `Ident`. --- xrbk_macro/src/element.rs | 30 +++++++++++++----------- xrbk_macro/src/element/expansion/xrbk.rs | 12 +++++----- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/xrbk_macro/src/element.rs b/xrbk_macro/src/element.rs index c6d60513..a8aae000 100644 --- a/xrbk_macro/src/element.rs +++ b/xrbk_macro/src/element.rs @@ -474,13 +474,14 @@ impl Element { } } - /// Whether this `Element` has an `ignore` attribute that contains the trait - /// specified by `ident`. - pub fn is_ignoring_trait(&self, ident: Ident) -> bool { + /// Whether this `Element` has a [`HideAttribute`] specifying the given + /// `trait`. + pub fn is_ignoring_trait(&self, r#trait: &str) -> bool { if let Element::Field(field) = self { - return field.is_ignoring_trait(ident); + field.is_ignoring_trait(r#trait) + } else { + false } - false } } @@ -613,15 +614,16 @@ impl Field { self.error_data_attribute.is_some() } - /// Whether this `Element` has an `ignore` attribute that contains the trait - /// specified by `ident`. - pub fn is_ignoring_trait(&self, ident: Ident) -> bool { - let Some(hide) = &self.hide_attribute else { - return false; - }; - hide.hidden_traits - .iter() - .any(|r#trait| r#trait.is_ident(&ident)) + /// Whether this `Field` has a [`HideAttribute`] specifying the given + /// `trait`. + pub fn is_ignoring_trait(&self, r#trait: &str) -> bool { + if let Some(hide_attribute) = &self.hide_attribute { + hide_attribute.hidden_traits + .iter() + .any(|path| path.is_ident(r#trait)) + } else { + false + } } } diff --git a/xrbk_macro/src/element/expansion/xrbk.rs b/xrbk_macro/src/element/expansion/xrbk.rs index 619095e3..c3f90b25 100644 --- a/xrbk_macro/src/element/expansion/xrbk.rs +++ b/xrbk_macro/src/element/expansion/xrbk.rs @@ -12,7 +12,7 @@ impl Element { pub fn write_tokens(&self, tokens: &mut TokenStream2, definition_type: DefinitionType) { match self { Self::Field(field) => { - if !field.is_ignoring_trait(format_ident!("Writable")) { + if !field.is_ignoring_trait("Writable") { field.write_tokens(tokens) } }, @@ -26,7 +26,7 @@ impl Element { pub fn x11_size_tokens(&self, tokens: &mut TokenStream2, definition_type: DefinitionType) { match self { Self::Field(field) => { - if !field.is_ignoring_trait(format_ident!("X11Size")) { + if !field.is_ignoring_trait("X11Size") { field.x11_size_tokens(tokens) } }, @@ -40,7 +40,7 @@ impl Element { pub fn read_tokens(&self, tokens: &mut TokenStream2, definition_type: DefinitionType) { match self { Self::Field(field) => { - if !field.is_ignoring_trait(format_ident!("Readable")) + if !field.is_ignoring_trait("Readable") || field.context_attribute.is_some() { field.read_tokens(tokens) @@ -56,7 +56,7 @@ impl Element { pub fn add_x11_size_tokens(&self, tokens: &mut TokenStream2) { match self { Self::Field(field) => { - if !field.is_ignoring_trait(format_ident!("X11Size")) { + if !field.is_ignoring_trait("X11Size") { field.add_x11_size_tokens(tokens) } }, @@ -69,7 +69,7 @@ impl Element { pub fn partial_eq_tokens(&self, tokens: &mut TokenStream2) { if let Self::Field(field) = self { - if !field.is_ignoring_trait(format_ident!("PartialEq")) { + if !field.is_ignoring_trait("PartialEq") { field.add_partial_eq_tokens(tokens) } } @@ -77,7 +77,7 @@ impl Element { pub fn hash_tokens(&self, tokens: &mut TokenStream2) { if let Self::Field(field) = self { - if !field.is_ignoring_trait(format_ident!("Hash")) { + if !field.is_ignoring_trait("Hash") { field.add_hash_tokens(tokens) } } From 4fd96cbc0cb40d5e8c6c1cc8e319b7f470333b39 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 16 Jan 2023 17:11:19 +0000 Subject: [PATCH 11/17] [CI510] formatted code with rustfmt --- xrbk_macro/src/element.rs | 3 ++- xrbk_macro/src/element/expansion/xrbk.rs | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/xrbk_macro/src/element.rs b/xrbk_macro/src/element.rs index a8aae000..e787c029 100644 --- a/xrbk_macro/src/element.rs +++ b/xrbk_macro/src/element.rs @@ -618,7 +618,8 @@ impl Field { /// `trait`. pub fn is_ignoring_trait(&self, r#trait: &str) -> bool { if let Some(hide_attribute) = &self.hide_attribute { - hide_attribute.hidden_traits + hide_attribute + .hidden_traits .iter() .any(|path| path.is_ident(r#trait)) } else { diff --git a/xrbk_macro/src/element/expansion/xrbk.rs b/xrbk_macro/src/element/expansion/xrbk.rs index c3f90b25..84559a4e 100644 --- a/xrbk_macro/src/element/expansion/xrbk.rs +++ b/xrbk_macro/src/element/expansion/xrbk.rs @@ -40,9 +40,7 @@ impl Element { pub fn read_tokens(&self, tokens: &mut TokenStream2, definition_type: DefinitionType) { match self { Self::Field(field) => { - if !field.is_ignoring_trait("Readable") - || field.context_attribute.is_some() - { + if !field.is_ignoring_trait("Readable") || field.context_attribute.is_some() { field.read_tokens(tokens) } }, From 0e0027e56026a3e02032ab1453f628dea45df3db Mon Sep 17 00:00:00 2001 From: Syudagye Date: Mon, 16 Jan 2023 20:01:11 +0100 Subject: [PATCH 12/17] XRBK macro: Applied some requested changes --- xrbk_macro/src/attribute.rs | 7 +++++-- xrbk_macro/src/attribute/parsing.rs | 2 +- xrbk_macro/src/definition/expansion/derives.rs | 4 ---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/xrbk_macro/src/attribute.rs b/xrbk_macro/src/attribute.rs index 952199dd..e7261b57 100644 --- a/xrbk_macro/src/attribute.rs +++ b/xrbk_macro/src/attribute.rs @@ -136,8 +136,11 @@ pub struct HideAttribute { /// A pair of square brackets (`(` and `)`) surrounding the `hidden_traits`. pub paren_token: token::Paren, - /// A list of traits which will ingore this field on their implementations. - /// It uses the same style has the derive macro. + /// A list of traits which will ignore this field in their derived + /// implementations. + /// + /// See the [`HideAttribute`] syntax section for which traits are allowed + /// here. pub hidden_traits: Punctuated, } diff --git a/xrbk_macro/src/attribute/parsing.rs b/xrbk_macro/src/attribute/parsing.rs index 6e64bf32..c6fb47ab 100644 --- a/xrbk_macro/src/attribute/parsing.rs +++ b/xrbk_macro/src/attribute/parsing.rs @@ -224,7 +224,7 @@ impl ParseWithContext for ParsedAttributes { { return Err(syn::Error::new( hide_attribute.span(), - "Cannot hide `Readable` without a context attribute to read the field", + "cannot hide this field when implementing Readable without a #[context(...)] attribute", )); } diff --git a/xrbk_macro/src/definition/expansion/derives.rs b/xrbk_macro/src/definition/expansion/derives.rs index 84ad379d..80486b04 100644 --- a/xrbk_macro/src/definition/expansion/derives.rs +++ b/xrbk_macro/src/definition/expansion/derives.rs @@ -29,9 +29,7 @@ macro_rules! structlike_impl_partial_eq { impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { #[allow(clippy::nonminimal_bool)] fn eq(&self, other: &Self) -> bool { - // Default value which will be compared to all checked fields true - // All the fields checks #eqs } @@ -94,9 +92,7 @@ impl Enum { tokens.append_tokens(quote_spanned!(trait_path.span()=> Self::#ident #pat => { - // Default value which will be compared to all checked fields true - // All the fields checks #eqs }, From b4a5c913fb45b9454da46dad5c2ef2909c20cd5c Mon Sep 17 00:00:00 2001 From: Syudagye Date: Thu, 19 Jan 2023 12:04:05 +0100 Subject: [PATCH 13/17] XRBK macro: Moved to `derivative` for `ParialEq` and `Hash` --- Cargo.toml | 1 + src/x11/event.rs | 6 +- xrbk_macro/src/attribute.rs | 2 - xrbk_macro/src/attribute/parsing.rs | 18 -- xrbk_macro/src/definition/expansion.rs | 41 ----- .../src/definition/expansion/derives.rs | 155 ------------------ xrbk_macro/src/element/expansion/xrbk.rs | 36 ---- xrbk_macro/src/lib.rs | 2 - 8 files changed, 5 insertions(+), 256 deletions(-) delete mode 100644 xrbk_macro/src/definition/expansion/derives.rs diff --git a/Cargo.toml b/Cargo.toml index 1bac488b..e688add2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,3 +30,4 @@ bitflags = "1.3" # bit masks - representations of masks thiserror = "1" # error handling derive_more = "0.99" # derive more useful traits xrbk_macro = { path = "./xrbk_macro" } # generation of XRB structures +derivative = "2.2.0" diff --git a/src/x11/event.rs b/src/x11/event.rs index 0776cc47..d18ab0b8 100644 --- a/src/x11/event.rs +++ b/src/x11/event.rs @@ -27,13 +27,15 @@ use crate::{ }; use bitflags::bitflags; +use derivative::Derivative; use xrbk::{Buf, ConstantX11Size, ReadResult, Readable, ReadableWithContext, X11Size}; use xrbk_macro::{derive_xrb, ConstantX11Size, Readable, Writable, X11Size}; extern crate self as xrb; derive_xrb! { - #[derive(Debug, Hash, PartialEq, Eq, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a key is pressed. /// /// This [event] is generated for all keys: that includes modifier keys. @@ -47,7 +49,7 @@ derive_xrb! { /// [`KEY_PRESS`]: crate::mask::EventMask::KEY_PRESS pub struct KeyPress: Event(2) { #[sequence] - #[hide(PartialEq, Hash)] + #[derivative(PartialEq="ignore", Hash="ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// diff --git a/xrbk_macro/src/attribute.rs b/xrbk_macro/src/attribute.rs index e7261b57..60b6752a 100644 --- a/xrbk_macro/src/attribute.rs +++ b/xrbk_macro/src/attribute.rs @@ -116,8 +116,6 @@ pub struct ErrorDataAttribute { /// >       `Readable` \ /// >    | `Writable` \ /// >    | `X11Size` \ -/// >    | `PartialEq` \ -/// >    | `Hash` \ /// > /// > [^hidden-traits]: *HideAttribute*s may only specify traits listed in /// > *HiddenTraits*, any diff --git a/xrbk_macro/src/attribute/parsing.rs b/xrbk_macro/src/attribute/parsing.rs index c6fb47ab..5618f6d4 100644 --- a/xrbk_macro/src/attribute/parsing.rs +++ b/xrbk_macro/src/attribute/parsing.rs @@ -47,8 +47,6 @@ pub struct ParsedItemAttributes { pub derive_writables: Punctuated, pub derive_readables: Punctuated, pub derive_readable_with_contexts: Punctuated, - pub derive_partial_eqs: Punctuated, - pub derive_hashes: Punctuated, } impl ParsedItemAttributes { @@ -251,8 +249,6 @@ impl Parse for ParsedItemAttributes { let mut derive_writables = Punctuated::new(); let mut derive_readables = Punctuated::new(); let mut derive_readable_with_contexts = Punctuated::new(); - let mut derive_partial_eqs = Punctuated::new(); - let mut derive_hashes = Punctuated::new(); while input.peek(Token![#]) && input.peek2(token::Bracket) { let content; @@ -307,18 +303,6 @@ impl Parse for ParsedItemAttributes { if let Some(comma) = comma { derive_readable_with_contexts.push_punct(comma); } - } else if path.is_ident("PartialEq") { - derive_partial_eqs.push_value(path); - - if let Some(comma) = comma { - derive_partial_eqs.push_punct(comma); - } - } else if path.is_ident("Hash") { - derive_hashes.push_value(path); - - if let Some(comma) = comma { - derive_hashes.push_punct(comma); - } } else { paths.push(path); @@ -364,8 +348,6 @@ impl Parse for ParsedItemAttributes { derive_writables, derive_readables, derive_readable_with_contexts, - derive_partial_eqs, - derive_hashes, }) } } diff --git a/xrbk_macro/src/definition/expansion.rs b/xrbk_macro/src/definition/expansion.rs index bfeafab8..270cec5a 100644 --- a/xrbk_macro/src/definition/expansion.rs +++ b/xrbk_macro/src/definition/expansion.rs @@ -2,7 +2,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -mod derives; mod message_trait; mod readable; mod writable; @@ -42,14 +41,6 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { r#struct.impl_x11_size(tokens, path); } - - for path in &attrs.derive_partial_eqs { - r#struct.impl_partial_eq(tokens, path); - } - - for path in &attrs.derive_hashes { - r#struct.impl_hash(tokens, path); - } }, Self::Enum(r#enum) => { @@ -68,14 +59,6 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { r#enum.impl_x11_size(tokens, path); } - - for path in &attrs.derive_partial_eqs { - r#enum.impl_partial_eq(tokens, path); - } - - for path in &attrs.derive_hashes { - r#enum.impl_hash(tokens, path); - } }, Self::Request(request) => { @@ -95,14 +78,6 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { request.impl_x11_size(tokens, path); } - - for path in &attrs.derive_partial_eqs { - request.impl_partial_eq(tokens, path); - } - - for path in &attrs.derive_hashes { - request.impl_hash(tokens, path); - } }, Self::Reply(reply) => { @@ -122,14 +97,6 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { reply.impl_x11_size(tokens, path); } - - for path in &attrs.derive_partial_eqs { - reply.impl_partial_eq(tokens, path); - } - - for path in &attrs.derive_hashes { - reply.impl_hash(tokens, path); - } }, Self::Event(event) => { @@ -149,14 +116,6 @@ impl ToTokens for Definition { for path in &attrs.derive_x11_sizes { event.impl_x11_size(tokens, path); } - - for path in &attrs.derive_partial_eqs { - event.impl_partial_eq(tokens, path); - } - - for path in &attrs.derive_hashes { - event.impl_hash(tokens, path); - } }, Self::Error(error) => { diff --git a/xrbk_macro/src/definition/expansion/derives.rs b/xrbk_macro/src/definition/expansion/derives.rs deleted file mode 100644 index 80486b04..00000000 --- a/xrbk_macro/src/definition/expansion/derives.rs +++ /dev/null @@ -1,155 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -use super::*; -use crate::ext::TsExt; -use proc_macro2::TokenStream as TokenStream2; -use quote::quote_spanned; -use syn::Path; - -macro_rules! structlike_impl_partial_eq { - ($def:path) => { - impl $def { - pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { - let ident = &self.ident; - - // TODO: add generic bounds - let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); - - // Expand the tokens to read each element. - let eqs = TokenStream2::with_tokens(|tokens| { - for element in &self.content { - element.partial_eq_tokens(tokens); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - #[automatically_derived] - impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { - #[allow(clippy::nonminimal_bool)] - fn eq(&self, other: &Self) -> bool { - true - // All the fields checks - #eqs - } - } - )); - } - - pub fn impl_hash(&self, tokens: &mut TokenStream2, trait_path: &Path) { - let ident = &self.ident; - - // TODO: add generic bounds - let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); - - // Expand the tokens to read each element. - let hashes = TokenStream2::with_tokens(|tokens| { - for element in &self.content { - element.hash_tokens(tokens); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - #[automatically_derived] - impl #impl_generics ::core::hash::Hash for #ident #type_generics #where_clause { - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { - // All the hashes for all fiels - #hashes - } - } - )); - } - } - }; -} - -structlike_impl_partial_eq!(Struct); -structlike_impl_partial_eq!(Request); -structlike_impl_partial_eq!(Reply); -structlike_impl_partial_eq!(Event); - -impl Enum { - pub fn impl_partial_eq(&self, tokens: &mut TokenStream2, trait_path: &Path) { - let ident = &self.ident; - - // TODO: add generic bounds - let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); - - let arms = TokenStream2::with_tokens(|tokens| { - for variant in &self.variants { - let ident = &variant.ident; - - let pat = TokenStream2::with_tokens(|tokens| { - variant.content.pat_cons_to_tokens(tokens); - }); - - let eqs = TokenStream2::with_tokens(|tokens| { - for element in &variant.content { - element.partial_eq_tokens(tokens); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - Self::#ident #pat => { - true - // All the fields checks - #eqs - }, - )); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - #[automatically_derived] - impl #impl_generics ::std::cmp::PartialEq for #ident #type_generics #where_clause { - fn eq(&self, other: &Self) -> bool { - match self { - #arms - } - } - } - )); - } - - pub fn impl_hash(&self, tokens: &mut TokenStream2, trait_path: &Path) { - let ident = &self.ident; - - // TODO: add generic bounds - let (impl_generics, type_generics, where_clause) = self.generics.split_for_impl(); - - let arms = TokenStream2::with_tokens(|tokens| { - for variant in &self.variants { - let ident = &variant.ident; - - let pat = TokenStream2::with_tokens(|tokens| { - variant.content.pat_cons_to_tokens(tokens); - }); - - let hashes = TokenStream2::with_tokens(|tokens| { - for element in &variant.content { - element.hash_tokens(tokens); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - Self::#ident #pat => { - // All the hashes for all fiels - #hashes - }, - )); - } - }); - - tokens.append_tokens(quote_spanned!(trait_path.span()=> - #[automatically_derived] - impl #impl_generics ::core::hash::Hash for #ident #type_generics #where_clause { - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { - match self { - #arms - } - } - } - )); - } -} diff --git a/xrbk_macro/src/element/expansion/xrbk.rs b/xrbk_macro/src/element/expansion/xrbk.rs index 84559a4e..b1d1ff01 100644 --- a/xrbk_macro/src/element/expansion/xrbk.rs +++ b/xrbk_macro/src/element/expansion/xrbk.rs @@ -64,22 +64,6 @@ impl Element { Self::ArrayUnused(unused) => unused.add_x11_size_tokens(tokens), } } - - pub fn partial_eq_tokens(&self, tokens: &mut TokenStream2) { - if let Self::Field(field) = self { - if !field.is_ignoring_trait("PartialEq") { - field.add_partial_eq_tokens(tokens) - } - } - } - - pub fn hash_tokens(&self, tokens: &mut TokenStream2) { - if let Self::Field(field) = self { - if !field.is_ignoring_trait("Hash") { - field.add_hash_tokens(tokens) - } - } - } } // Field {{{ @@ -161,26 +145,6 @@ impl Field { ) }); } - - pub fn add_partial_eq_tokens(&self, tokens: &mut TokenStream2) { - tokens.append_tokens({ - let ident = &self.id; - - quote_spanned!(self.span()=> - && self.#ident == other.#ident - ) - }); - } - - pub fn add_hash_tokens(&self, tokens: &mut TokenStream2) { - tokens.append_tokens({ - let ident = &self.id; - - quote_spanned!(self.span()=> - ::core::hash::Hash::hash(&self.#ident, state); - ) - }); - } } // }}} Let {{{ diff --git a/xrbk_macro/src/lib.rs b/xrbk_macro/src/lib.rs index dbd0ed1a..a59e3eeb 100644 --- a/xrbk_macro/src/lib.rs +++ b/xrbk_macro/src/lib.rs @@ -383,8 +383,6 @@ pub fn derive_constant_x11_size(item: TokenStream) -> TokenStream { /// >       `Readable` \ /// >    | `Writable` \ /// >    | `X11Size` \ -/// >    | `PartialEq` \ -/// >    | `Hash` \ /// > /// > [^hidden-traits]: *HideAttribute*s may only specify traits listed in /// > *HiddenTraits*, any From 3632ebf9b8790108b2609b0bbb7a9310fa64b429 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 19 Jan 2023 11:07:18 +0000 Subject: [PATCH 14/17] [CI608] formatted code with rustfmt --- src/x11/event.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11/event.rs b/src/x11/event.rs index d18ab0b8..b142ad3c 100644 --- a/src/x11/event.rs +++ b/src/x11/event.rs @@ -35,7 +35,7 @@ extern crate self as xrb; derive_xrb! { #[derive(Debug, Derivative, X11Size, Readable, Writable)] - #[derivative(Hash, PartialEq, Eq)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a key is pressed. /// /// This [event] is generated for all keys: that includes modifier keys. From c1e8f9f3473995b57416e6ba8ef54fe2c1f16183 Mon Sep 17 00:00:00 2001 From: Syudagye Date: Sun, 22 Jan 2023 17:09:29 +0100 Subject: [PATCH 15/17] XRBK macro: Applied requested changes --- src/x11/event.rs | 2 +- xrbk_macro/src/attribute.rs | 2 +- xrbk_macro/src/attribute/parsing.rs | 7 ++----- xrbk_macro/src/lib.rs | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/x11/event.rs b/src/x11/event.rs index 3c379f42..1efd3535 100644 --- a/src/x11/event.rs +++ b/src/x11/event.rs @@ -50,7 +50,7 @@ derive_xrb! { /// [`KEY_PRESS`]: crate::EventMask::KEY_PRESS pub struct KeyPress: Event(2) { #[sequence] - #[derivative(PartialEq="ignore", Hash="ignore")] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// diff --git a/xrbk_macro/src/attribute.rs b/xrbk_macro/src/attribute.rs index 60b6752a..aed40975 100644 --- a/xrbk_macro/src/attribute.rs +++ b/xrbk_macro/src/attribute.rs @@ -102,7 +102,7 @@ pub struct ErrorDataAttribute { } /// An attribute which indicates that a [`Field`] should not be taken into -/// consideration when implementing traits. +/// consideration when implementing XRBK traits. /// /// > **Syntax**\ /// > _HideAttribute_ :\ diff --git a/xrbk_macro/src/attribute/parsing.rs b/xrbk_macro/src/attribute/parsing.rs index 5618f6d4..573730fa 100644 --- a/xrbk_macro/src/attribute/parsing.rs +++ b/xrbk_macro/src/attribute/parsing.rs @@ -189,15 +189,12 @@ impl ParseWithContext for ParsedAttributes { } let inner_content; - let paren_token = parenthesized!(inner_content in content); - let hidden_traits = inner_content.parse_terminated(Path::parse)?; - hide_attribute = Some(HideAttribute { hash_token, bracket_token, path, - paren_token, - hidden_traits, + paren_token: parenthesized!(inner_content in content), + hidden_traits: inner_content.parse_terminated(Path::parse)?, }); // Otherwise, if the name was not `context`, `metabyte`, nor // `sequence`, parse the attribute as a normal attribute. diff --git a/xrbk_macro/src/lib.rs b/xrbk_macro/src/lib.rs index a59e3eeb..368280f9 100644 --- a/xrbk_macro/src/lib.rs +++ b/xrbk_macro/src/lib.rs @@ -386,7 +386,7 @@ pub fn derive_constant_x11_size(item: TokenStream) -> TokenStream { /// > /// > [^hidden-traits]: *HideAttribute*s may only specify traits listed in /// > *HiddenTraits*, any -/// > other traits will have no effects. +/// > other traits will have no effect. /// > /// > _Source_ :\ /// >    ( _SourceArgs_ `=>` )? [_Expression_] From 4e2610c42f7f5e9ae22dfec0a820ef430fb58c89 Mon Sep 17 00:00:00 2001 From: Syudagye Date: Sun, 22 Jan 2023 17:24:55 +0100 Subject: [PATCH 16/17] Added `PartialEq` and `Hash` derives for all events and errors Using `derivative` so we can ignore all the sequences fields --- src/x11/error.rs | 69 +++++++++++++++++++------- src/x11/event.rs | 124 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 145 insertions(+), 48 deletions(-) diff --git a/src/x11/error.rs b/src/x11/error.rs index 1faa3169..77eec6c1 100644 --- a/src/x11/error.rs +++ b/src/x11/error.rs @@ -13,11 +13,13 @@ use crate::message::Error; +use derivative::Derivative; use xrbk_macro::derive_xrb; extern crate self as xrb; derive_xrb! { - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [major opcode] and [minor opcode] /// combination provided in a [request] does not specify a valid [request]. /// @@ -27,6 +29,7 @@ derive_xrb! { /// [minor opcode]: crate::message::Request::MINOR_OPCODE pub struct Request: Error(1) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -61,7 +64,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when a numerical value contained in the [request] /// falls outside of the range of accepted values. /// @@ -72,6 +76,7 @@ derive_xrb! { /// [error]: Error pub struct Value: Error(2) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -108,7 +113,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [`Window`] ID used in the [request] does /// not refer to a defined [window]. /// @@ -118,6 +124,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct Window: Error(3) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -154,7 +161,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [`Pixmap`] ID used in the [request] does /// not refer to a defined [pixmap]. /// @@ -164,6 +172,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct Pixmap: Error(4) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -200,7 +209,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [`Atom`] ID used in the [request] does /// not refer to a defined [atom]. /// @@ -210,6 +220,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct Atom: Error(5) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -246,7 +257,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [`CursorAppearance`] ID used in the /// [request] does not refer to a defined [cursor appearance]. /// @@ -256,6 +268,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct CursorAppearance: Error(6) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -293,7 +306,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [`Font`] ID used in the [request] does /// not refer to a defined [font]. /// @@ -303,6 +317,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct Font: Error(7) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -339,7 +354,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when there is a mismatch of some kind. /// /// This [error] is generated for a number of reasons: @@ -358,6 +374,7 @@ derive_xrb! { /// [graphics context]: crate::GraphicsContext pub struct Match: Error(8) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -384,7 +401,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [`Drawable`] ID used in the [request] /// does not refer to a defined [window] or [pixmap]. /// @@ -395,6 +413,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct Drawable: Error(9) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -432,7 +451,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when access is not allowed for what the [request] is /// trying to do. /// @@ -459,6 +479,7 @@ derive_xrb! { /// [colormap]: crate::Colormap pub struct Access: Error(10) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -485,13 +506,15 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the X server failed to allocate the requested /// resource. /// /// [error]: Error pub struct Alloc: Error(11) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -518,7 +541,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [`Colormap`] ID used in the [request] /// does not refer to a defined [colormap]. /// @@ -528,6 +552,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct Colormap: Error(12) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -564,7 +589,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [`GraphicsContext`] ID used in the [request] /// does not refer to a defined [graphics context]. /// @@ -574,6 +600,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct GraphicsContext: Error(13) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -610,13 +637,15 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when a chosen resource ID is not in the range of /// resource IDs assigned to the client, or the ID is already in use. /// /// [error]: Error pub struct ResourceIdChoice: Error(14) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -648,7 +677,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the [request] specifies the name of a [font] /// or color which does not exist. /// @@ -657,6 +687,7 @@ derive_xrb! { /// [font]: crate::Font pub struct Name: Error(15) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -683,7 +714,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when a [request] is not of the correct length. /// /// The length may be too short or too long to hold the fields defined for @@ -694,6 +726,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct Length: Error(16) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// @@ -720,7 +753,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, Writable, Readable, X11Size)] + #[derive(Debug, Derivative, Writable, Readable, X11Size)] + #[derivative(Hash, PartialEq, Eq)] /// An [error] generated when the X server does not implement some aspect /// of the [request]. /// @@ -728,6 +762,7 @@ derive_xrb! { /// [request]: crate::message::Request pub struct Implementation: Error(17) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The sequence number identifying the [request] that was /// sent. /// diff --git a/src/x11/event.rs b/src/x11/event.rs index 1efd3535..ccd24a78 100644 --- a/src/x11/event.rs +++ b/src/x11/event.rs @@ -117,7 +117,8 @@ derive_xrb! { _, } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a key is released. /// /// This [event] is generated for all keys: that includes modifier keys. @@ -130,6 +131,7 @@ derive_xrb! { /// [`KEY_RELEASE`]: crate::EventMask::KEY_RELEASE pub struct KeyRelease: Event(3) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -200,7 +202,8 @@ derive_xrb! { _, } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [mouse button] is pressed. /// /// # Recipients @@ -212,6 +215,7 @@ derive_xrb! { /// [`BUTTON_PRESS`]: crate::EventMask::BUTTON_PRESS pub struct ButtonPress: Event(4) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -280,7 +284,8 @@ derive_xrb! { _, } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [mouse button] is released. /// /// # Recipients @@ -292,6 +297,7 @@ derive_xrb! { /// [`BUTTON_RELEASE`]: crate::EventMask::BUTTON_RELEASE pub struct ButtonRelease: Event(5) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -393,7 +399,8 @@ pub enum MotionNotificationType { } derive_xrb! { - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when the cursor moves within a [window]. /// /// `Motion` events are only generated when the cursor motion begins and ends @@ -435,6 +442,7 @@ derive_xrb! { /// [window]: Window pub struct Motion: Event(6) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -620,7 +628,8 @@ bitflags! { } derive_xrb! { - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when the cursor enters a [window]. /// /// This [event] is triggered both when the cursor moves to be in a different @@ -638,6 +647,7 @@ derive_xrb! { /// [`ENTER_WINDOW`]: crate::EventMask::ENTER_WINDOW pub struct EnterWindow: Event(7) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -709,7 +719,8 @@ derive_xrb! { pub mask: EnterLeaveMask, } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when the cursor leaves a [window]. /// /// This event is triggered both when the cursor moves to be in a different @@ -727,6 +738,7 @@ derive_xrb! { /// [`LEAVE_WINDOW`]: crate::EventMask::LEAVE_WINDOW pub struct LeaveWindow: Event(8) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -995,7 +1007,8 @@ pub enum FocusGrabMode { } derive_xrb! { - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] is focused. /// /// `Focus` events generated when the keyboard is not grabbed have @@ -1014,6 +1027,7 @@ derive_xrb! { /// [`FOCUS_CHANGE`]: crate::EventMask::FOCUS_CHANGE pub struct Focus: Event(9) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1052,7 +1066,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] is unfocused. /// /// `Unfocus` events generated when the keyboard is not grabbed have @@ -1071,6 +1086,7 @@ derive_xrb! { /// [`FOCUS_CHANGE`]: crate::EventMask::FOCUS_CHANGE pub struct Unfocus: Event(10) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1131,7 +1147,8 @@ derive_xrb! { pub keys: [u8; 31], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a rectangular area of a [window] needs to be /// rendered. /// @@ -1163,6 +1180,7 @@ derive_xrb! { /// [`EXPOSURE`]: crate::EventMask::EXPOSURE pub struct Expose: Event(12) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1184,7 +1202,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when using graphics operations when a region of a /// source [`Drawable`] is obscured. /// @@ -1200,6 +1219,7 @@ derive_xrb! { /// [`graphics_exposure`]: crate::set::GraphicsOptions::graphics_exposure pub struct GraphicsExposure: Event(13) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1239,7 +1259,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a graphics request which might generate /// [`GraphicsExposure` events] doesn't generate any. /// @@ -1253,6 +1274,7 @@ derive_xrb! { /// [`graphics_exposure`]: crate::set::GraphicsOptions::graphics_exposure pub struct NoExposure: Event(14) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1322,7 +1344,8 @@ pub enum VisibilityState { } derive_xrb! { - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when changes to a [window]'s visibility occur. /// /// The [window]'s visibility is calculated ignoring all of its subwindows. @@ -1355,6 +1378,7 @@ derive_xrb! { /// [`VISIBILITY_CHANGE`]: crate::EventMask::VISIBILITY_CHANGE pub struct Visibility: Event(15) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1370,7 +1394,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] is created. /// /// # Recipients @@ -1382,6 +1407,7 @@ derive_xrb! { /// [`SUBSTRUCTURE_NOTIFY`]: crate::EventMask::SUBSTRUCTURE_NOTIFY pub struct Create: Event(16) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1423,7 +1449,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] is destroyed. /// /// # Recipients @@ -1437,6 +1464,7 @@ derive_xrb! { /// [`SUBSTRUCTURE_NOTIFY`]: crate::EventMask::SUBSTRUCTURE_NOTIFY pub struct Destroy: Event(17) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1459,7 +1487,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] is unmapped. /// /// Unmapping a [window] is the X term for hiding it. This is commonly used to @@ -1475,6 +1504,7 @@ derive_xrb! { /// [`SUBSTRUCTURE_NOTIFY`]: crate::EventMask::SUBSTRUCTURE_NOTIFY pub struct Unmap: Event(18) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1505,7 +1535,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] is mapped. /// /// Mapping a [window] is the X term for showing it. It is the reverse of @@ -1521,6 +1552,7 @@ derive_xrb! { /// [`SUBSTRUCTURE_NOTIFY`]: crate::EventMask::SUBSTRUCTURE_NOTIFY pub struct Map: Event(19) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1556,7 +1588,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when an unmapped [window] with an /// [`override_redirect` attribute] of `false` sends a [`MapWindow` request]. /// @@ -1574,6 +1607,7 @@ derive_xrb! { /// [`SUBSTRUCTURE_REDIRECT`]: crate::EventMask::SUBSTRUCTURE_REDIRECT pub struct MapRequest: Event(20) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1591,7 +1625,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] is reparented. /// /// Reparenting a [window] means to remove it from its current position in @@ -1608,6 +1643,7 @@ derive_xrb! { /// [`STRUCTURE_NOTIFY`]: crate::EventMask::STRUCTURE_NOTIFY pub struct Reparent: Event(21) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1649,7 +1685,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [`ConfigureWindow` request] changes the state /// of a [window]. /// @@ -1664,6 +1701,7 @@ derive_xrb! { /// [`SUBSTRUCTURE_NOTIFY`]: crate::EventMask::SUBSTRUCTURE_NOTIFY pub struct Configure: Event(22) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1720,7 +1758,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] sends a [`ConfigureWindow` request]. /// /// This [event] is generated when a client other than the one selecting @@ -1744,6 +1783,7 @@ derive_xrb! { /// [`SUBSTRUCTURE_REDIRECT`]: crate::EventMask::SUBSTRUCTURE_REDIRECT pub struct ConfigureWindowRequest: Event(23) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1793,7 +1833,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] is moved because its parent is /// resized. /// @@ -1807,6 +1848,7 @@ derive_xrb! { /// [`SUBSTRUCTURE_NOTIFY`]: crate::EventMask::SUBSTRUCTURE_NOTIFY pub struct Gravity: Event(24) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1833,7 +1875,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] on which a client is selecting /// [`RESIZE_REDIRECT`] has a [`ConfigureWindow` request] sent by another /// client attempt to change the [window]'s size. @@ -1848,6 +1891,7 @@ derive_xrb! { /// [`ConfigureWindow` request]: super::request::ConfigureWindow pub struct ResizeRequest: Event(25) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1892,7 +1936,8 @@ pub enum Placement { } derive_xrb! { - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] is restacked due to a /// [`CirculateWindow` request]. /// @@ -1908,6 +1953,7 @@ derive_xrb! { /// [`SUBSTRUCTURE_NOTIFY`]: crate::EventMask::SUBSTRUCTURE_NOTIFY pub struct Circulate: Event(26) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1935,7 +1981,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [`CirculateWindow` request] is sent for a /// [window] and that [window] actually needs to be restacked. /// @@ -1949,6 +1996,7 @@ derive_xrb! { /// [`CirculateWindow` request]: super::request::CirculateWindow pub struct CirculateRequest: Event(27) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -1994,7 +2042,8 @@ pub enum PropertyChange { } derive_xrb! { - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window] property is added, modified, or /// removed. /// @@ -2007,6 +2056,7 @@ derive_xrb! { /// [`PROPERTY_CHANGE`]: crate::EventMask::PROPERTY_CHANGE pub struct Property: Event(28) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -2030,7 +2080,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a new selection owner is defined for a /// selection. /// @@ -2044,6 +2095,7 @@ derive_xrb! { /// [`SetSelectionOwner` request]: super::request::SetSelectionOwner pub struct SelectionClear: Event(29) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -2061,7 +2113,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [`ConvertSelection` request] is sent. /// /// The owner should convert the selection based on the specified target @@ -2080,6 +2133,7 @@ derive_xrb! { /// [`SendEvent` request]: super::request::SendEvent pub struct ConvertSelectionRequest: Event(30) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -2109,7 +2163,8 @@ derive_xrb! { [_; ..], } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// A reply to the [`ConvertSelection` request]. /// /// If the selection has no owner, this is generated by the X server. If the @@ -2125,6 +2180,7 @@ derive_xrb! { /// [`SendEvent` request]: super::request::SendEvent pub struct Selection: Event(31) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -2187,7 +2243,8 @@ derive_xrb! { Installed, } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [window]'s [colormap] is installed, /// uninstalled, or its [`colormap` attribute] is changed. /// @@ -2203,6 +2260,7 @@ derive_xrb! { /// [`COLORMAP_CHANGE`]: crate::EventMask::COLORMAP_CHANGE pub struct Colormap: Event(32) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -2287,7 +2345,8 @@ impl ReadableWithContext for ClientMessageData { } derive_xrb! { - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated by a [`SendEvent` request]. /// /// # Recipients @@ -2299,6 +2358,7 @@ derive_xrb! { /// [window]: Window pub struct ClientMessage: Event(33) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// @@ -2357,7 +2417,8 @@ pub enum MappingRequest { } derive_xrb! { - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Derivative, X11Size, Readable, Writable)] + #[derivative(Hash, PartialEq, Eq)] /// An [event] generated when a [`SetModifierMapping`], /// [`ChangeKeyboardMapping`], or [`SetCursorMapping`] request is successful. /// @@ -2370,6 +2431,7 @@ derive_xrb! { /// [`SetCursorMapping`]: super::request::SetCursorMapping pub struct MappingChange: Event(34) { #[sequence] + #[derivative(PartialEq = "ignore", Hash = "ignore")] /// The [sequence number] associated with the last [request] related /// to this [event] that was received before this [event] was generated. /// From 0275a3a1ffd80ac1d964ef14bd0129c5f6633954 Mon Sep 17 00:00:00 2001 From: Syudagye Date: Sun, 22 Jan 2023 17:36:42 +0100 Subject: [PATCH 17/17] Fixed forgotten derive --- src/x11/event.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11/event.rs b/src/x11/event.rs index ccd24a78..147b616d 100644 --- a/src/x11/event.rs +++ b/src/x11/event.rs @@ -2225,7 +2225,7 @@ derive_xrb! { InstalledOrUninstalled, } - #[derive(Debug, Hash, X11Size, Readable, Writable)] + #[derive(Debug, Hash, PartialEq, Eq, X11Size, Readable, Writable)] /// Whether a [window]'s [colormap] is currently installed. /// /// [window]: Window