summaryrefslogtreecommitdiffstats
path: root/third_party/rust/derive_more-impl/src/add_assign_like.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/derive_more-impl/src/add_assign_like.rs')
-rw-r--r--third_party/rust/derive_more-impl/src/add_assign_like.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/third_party/rust/derive_more-impl/src/add_assign_like.rs b/third_party/rust/derive_more-impl/src/add_assign_like.rs
new file mode 100644
index 0000000000..610ba983e0
--- /dev/null
+++ b/third_party/rust/derive_more-impl/src/add_assign_like.rs
@@ -0,0 +1,39 @@
+use crate::add_helpers::{struct_exprs, tuple_exprs};
+use crate::utils::{add_extra_ty_param_bound_op, named_to_vec, unnamed_to_vec};
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+use syn::{Data, DeriveInput, Fields};
+
+pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream {
+ let trait_ident = format_ident!("{trait_name}");
+ let method_name = trait_name.trim_end_matches("Assign").to_lowercase();
+ let method_ident = format_ident!("{method_name}_assign");
+ let input_type = &input.ident;
+
+ let generics = add_extra_ty_param_bound_op(&input.generics, &trait_ident);
+ let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+
+ let exprs = match input.data {
+ Data::Struct(ref data_struct) => match data_struct.fields {
+ Fields::Unnamed(ref fields) => {
+ tuple_exprs(&unnamed_to_vec(fields), &method_ident)
+ }
+ Fields::Named(ref fields) => {
+ struct_exprs(&named_to_vec(fields), &method_ident)
+ }
+ _ => panic!("Unit structs cannot use derive({trait_name})"),
+ },
+
+ _ => panic!("Only structs can use derive({trait_name})"),
+ };
+
+ quote! {
+ #[automatically_derived]
+ impl #impl_generics ::core::ops::#trait_ident for #input_type #ty_generics #where_clause {
+ #[inline]
+ fn #method_ident(&mut self, rhs: #input_type #ty_generics) {
+ #( #exprs; )*
+ }
+ }
+ }
+}