1use proc_macro2::TokenStream as TokenStream2;
17use syn::spanned::Spanned;
18use syn::{
19 Data, DeriveInput, Error, Fields, Index, Meta, MetaList, NestedMeta, Path, Result, Type,
20};
21
22use crate::util::get_amplify_crate;
23
24const NAME: &str = "wrapper";
25const EXAMPLE: &str = r#"#[wrapper(LowerHex, Add)]"#;
26
27#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Debug)]
28enum Wrapper {
29 NoRefs,
30 FromStr,
32 Display,
33 Debug,
34 Octal,
35 FromHex,
36 LowerHex,
37 UpperHex,
38 LowerExp,
39 UpperExp,
40 Deref,
42 AsRef,
43 AsSlice,
44 Borrow,
45 BorrowSlice,
46 Index,
48 IndexRange,
49 IndexFull,
50 IndexFrom,
51 IndexTo,
52 IndexInclusive,
53 IndexToInclusive,
54 Neg,
56 Add,
57 Sub,
58 Mul,
59 Div,
60 Rem,
61 Not,
63 Shl,
64 Shr,
65 BitAnd,
66 BitOr,
67 BitXor,
68 Hex,
70 Exp,
71 NumberFmt,
72 RangeOps,
73 MathOps,
74 BoolOps,
75 BitOps,
76}
77
78#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Debug)]
79enum WrapperMut {
80 NoRefs,
81 DerefMut,
83 AsMut,
84 AsSliceMut,
85 BorrowMut,
86 BorrowSliceMut,
87 IndexMut,
89 IndexRangeMut,
90 IndexFullMut,
91 IndexFromMut,
92 IndexToMut,
93 IndexInclusiveMut,
94 IndexToInclusiveMut,
95 AddAssign,
97 SubAssign,
98 MulAssign,
99 DivAssign,
100 RemAssign,
101 ShlAssign,
102 ShrAssign,
103 BitAndAssign,
105 BitOrAssign,
106 BitXorAssign,
107 RangeMut,
109 MathAssign,
110 BoolAssign,
111 BitAssign,
112}
113
114pub trait FromPath: Sized + Copy + Ord {
115 const IDENT: &'static str;
116 const NO_REFS: Self;
117 fn default_set() -> Vec<Self>;
118 fn is_not_ref(&self) -> bool;
119 fn from_path(path: &Path) -> Result<Option<Self>>;
120 fn populate(self, list: &mut Vec<Self>);
121}
122
123impl FromPath for Wrapper {
124 const IDENT: &'static str = "wrapper";
125 const NO_REFS: Self = Self::NoRefs;
126
127 fn default_set() -> Vec<Self> { vec![Wrapper::AsRef, Wrapper::Borrow] }
128
129 fn is_not_ref(&self) -> bool { *self != Wrapper::AsRef && *self != Wrapper::Borrow }
130
131 fn from_path(path: &Path) -> Result<Option<Self>> {
132 path.segments.first().map_or(
133 Err(attr_err!(path.span(), NAME, "must contain at least one identifier", EXAMPLE)),
134 |segment| {
135 Ok(match segment.ident.to_string().as_str() {
136 "FromStr" => Some(Wrapper::FromStr),
137 "Display" => Some(Wrapper::Display),
138 "Debug" => Some(Wrapper::Debug),
139 "Octal" => Some(Wrapper::Octal),
140 "FromHex" => Some(Wrapper::FromHex),
141 "LowerHex" => Some(Wrapper::LowerHex),
142 "UpperHex" => Some(Wrapper::UpperHex),
143 "LowerExp" => Some(Wrapper::LowerExp),
144 "UpperExp" => Some(Wrapper::UpperExp),
145 "NoRefs" => Some(Wrapper::NoRefs),
146 "AsRef" => Some(Wrapper::AsRef),
147 "AsSlice" => Some(Wrapper::AsSlice),
148 "Deref" => Some(Wrapper::Deref),
149 "Borrow" => Some(Wrapper::Borrow),
150 "BorrowSlice" => Some(Wrapper::BorrowSlice),
151 "Index" => Some(Wrapper::Index),
152 "IndexRange" => Some(Wrapper::IndexRange),
153 "IndexFull" => Some(Wrapper::IndexFull),
154 "IndexFrom" => Some(Wrapper::IndexFrom),
155 "IndexTo" => Some(Wrapper::IndexTo),
156 "IndexInclusive" => Some(Wrapper::IndexInclusive),
157 "IndexToInclusive" => Some(Wrapper::IndexToInclusive),
158 "Add" => Some(Wrapper::Add),
159 "Neg" => Some(Wrapper::Neg),
160 "Not" => Some(Wrapper::Not),
161 "Sub" => Some(Wrapper::Sub),
162 "Mul" => Some(Wrapper::Mul),
163 "Div" => Some(Wrapper::Div),
164 "Rem" => Some(Wrapper::Rem),
165 "Shl" => Some(Wrapper::Shl),
166 "Shr" => Some(Wrapper::Shr),
167 "BitAnd" => Some(Wrapper::BitAnd),
168 "BitOr" => Some(Wrapper::BitOr),
169 "BitXor" => Some(Wrapper::BitXor),
170
171 "Hex" => Some(Wrapper::Hex),
172 "Exp" => Some(Wrapper::Exp),
173 "NumberFmt" => Some(Wrapper::NumberFmt),
174 "RangeOps" => Some(Wrapper::RangeOps),
175 "MathOps" => Some(Wrapper::MathOps),
176 "BoolOps" => Some(Wrapper::BoolOps),
177 "BitOps" => Some(Wrapper::BitOps),
178 _ => None,
179 })
180 },
181 )
182 }
183
184 fn populate(self, list: &mut Vec<Self>) {
185 let ext = match self {
186 Wrapper::Hex => &[Wrapper::LowerHex, Wrapper::UpperHex, Wrapper::FromHex] as &[_],
187 Wrapper::Exp => &[Wrapper::LowerExp, Wrapper::UpperExp] as &[_],
188 Wrapper::NumberFmt => &[
189 Wrapper::LowerHex,
190 Wrapper::UpperHex,
191 Wrapper::LowerExp,
192 Wrapper::UpperExp,
193 Wrapper::Octal,
194 ] as &[_],
195 Wrapper::RangeOps => &[
196 Wrapper::IndexRange,
197 Wrapper::IndexFrom,
198 Wrapper::IndexTo,
199 Wrapper::IndexInclusive,
200 Wrapper::IndexToInclusive,
201 Wrapper::IndexFull,
202 ] as &[_],
203 Wrapper::MathOps => &[
204 Wrapper::Neg,
205 Wrapper::Add,
206 Wrapper::Sub,
207 Wrapper::Mul,
208 Wrapper::Div,
209 Wrapper::Rem,
210 ] as &[_],
211 Wrapper::BoolOps => {
212 &[Wrapper::Not, Wrapper::BitAnd, Wrapper::BitOr, Wrapper::BitXor] as &[_]
213 }
214 Wrapper::BitOps => &[
215 Wrapper::Not,
216 Wrapper::BitAnd,
217 Wrapper::BitOr,
218 Wrapper::BitXor,
219 Wrapper::Shl,
220 Wrapper::Shr,
221 ] as &[_],
222 x => {
223 list.push(x);
224 &[] as &[_]
225 }
226 };
227 list.extend(ext);
228 }
229}
230
231impl Wrapper {
232 pub fn into_token_stream2(
233 self,
234 input: &DeriveInput,
235 from: &Type,
236 field: &TokenStream2,
237 ) -> TokenStream2 {
238 let impl_generics_params = input.generics.params.clone();
239 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
240 let ident_name = &input.ident;
241 let amplify_crate = get_amplify_crate(input);
242
243 match self {
244 Wrapper::FromStr => quote! {
245 #[automatically_derived]
246 impl #impl_generics ::core::str::FromStr for #ident_name #ty_generics #where_clause
247 {
248 type Err = <<Self as #amplify_crate::Wrapper>::Inner as ::core::str::FromStr>::Err;
249
250 #[inline]
251 fn from_str(s: &str) -> Result<Self, Self::Err> {
252 use ::core::str::FromStr;
253 <#from as FromStr>::from_str(s).map(Self::from)
254 }
255 }
256 },
257 Wrapper::Display => quote! {
258 #[automatically_derived]
259 impl #impl_generics ::core::fmt::Display for #ident_name #ty_generics #where_clause
260 {
261 #[inline]
262 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
263 ::core::fmt::Display::fmt(&self.#field, f)
264 }
265 }
266 },
267 Wrapper::Debug => quote! {
268 #[automatically_derived]
269 impl #impl_generics ::core::fmt::Debug for #ident_name #ty_generics #where_clause
270 {
271 #[inline]
272 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
273 ::core::fmt::Debug::fmt(&self.#field, f)
274 }
275 }
276 },
277 Wrapper::Octal => quote! {
278 #[automatically_derived]
279 impl #impl_generics ::core::fmt::Octal for #ident_name #ty_generics #where_clause
280 {
281 #[inline]
282 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
283 ::core::fmt::Octal::fmt(&self.#field, f)
284 }
285 }
286 },
287 Wrapper::FromHex => quote! {
288 #[automatically_derived]
289 impl #impl_generics #amplify_crate::hex::FromHex for #ident_name #ty_generics #where_clause
290 {
291 #[inline]
292 fn from_byte_iter<I>(iter: I) -> Result<Self, #amplify_crate::hex::Error>
293 where
294 I: Iterator<Item = Result<u8, #amplify_crate::hex::Error>>
295 + ExactSizeIterator
296 + DoubleEndedIterator,
297 {
298 <#from as #amplify_crate::hex::FromHex>::from_byte_iter(iter).map(Self::from)
299 }
300 }
301 },
302 Wrapper::LowerHex => quote! {
303 #[automatically_derived]
304 impl #impl_generics ::core::fmt::LowerHex for #ident_name #ty_generics #where_clause
305 {
306 #[inline]
307 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
308 ::core::fmt::LowerHex::fmt(&self.#field, f)
309 }
310 }
311 },
312 Wrapper::UpperHex => quote! {
313 #[automatically_derived]
314 impl #impl_generics ::core::fmt::UpperHex for #ident_name #ty_generics #where_clause
315 {
316 #[inline]
317 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
318 ::core::fmt::UpperHex::fmt(&self.#field, f)
319 }
320 }
321 },
322 Wrapper::LowerExp => quote! {
323 #[automatically_derived]
324 impl #impl_generics ::core::fmt::LowerExp for #ident_name #ty_generics #where_clause
325 {
326 #[inline]
327 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
328 ::core::fmt::LowerExp::fmt(&self.#field, f)
329 }
330 }
331 },
332 Wrapper::UpperExp => quote! {
333 #[automatically_derived]
334 impl #impl_generics ::core::fmt::UpperExp for #ident_name #ty_generics #where_clause
335 {
336 #[inline]
337 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
338 ::core::fmt::UpperExp::fmt(&self.#field, f)
339 }
340 }
341 },
342 Wrapper::Deref => quote! {
343 #[automatically_derived]
344 impl #impl_generics ::core::ops::Deref for #ident_name #ty_generics #where_clause
345 {
346 type Target = #from;
347 #[inline]
348 fn deref(&self) -> &Self::Target {
349 &self.#field
350 }
351 }
352 },
353 Wrapper::AsRef => quote! {
354 #[automatically_derived]
355 impl #impl_generics ::core::convert::AsRef<#from> for #ident_name #ty_generics #where_clause {
356 #[inline]
357 fn as_ref(&self) -> &#from {
358 &self.#field
359 }
360 }
361 },
362 Wrapper::AsSlice => quote! {
363 #[automatically_derived]
364 impl #impl_generics AsRef<[u8]> for #ident_name #ty_generics #where_clause
365 {
366 #[inline]
367 fn as_ref(&self) -> &[u8] {
368 AsRef::<[u8]>::as_ref(&self.#field)
369 }
370 }
371 },
372 Wrapper::Borrow => quote! {
373 #[automatically_derived]
374 impl #impl_generics ::core::borrow::Borrow<#from> for #ident_name #ty_generics #where_clause {
375 #[inline]
376 fn borrow(&self) -> &#from {
377 &self.#field
378 }
379 }
380 },
381 Wrapper::BorrowSlice => quote! {
382 #[automatically_derived]
383 impl #impl_generics ::core::borrow::Borrow<[u8]> for #ident_name #ty_generics #where_clause
384 {
385 #[inline]
386 fn borrow(&self) -> &[u8] {
387 ::core::borrow::Borrow::<[u8]>::borrow(&self.#field)
388 }
389 }
390 },
391 Wrapper::Index => {
392 let where_clause = match where_clause {
393 None => quote! { where },
394 Some(_) => quote! { #where_clause },
395 };
396 quote! {
397 #[automatically_derived]
398 impl <#impl_generics_params> ::core::ops::Index<usize> for #ident_name #ty_generics #where_clause
399 {
400 type Output = <#from as ::core::ops::Index<usize>>::Output;
401
402 #[inline]
403 fn index(&self, index: usize) -> &Self::Output {
404 self.#field.index(index)
405 }
406 }
407 }
408 }
409 Wrapper::IndexRange => {
410 quote! {
411 #[automatically_derived]
412 impl <#impl_generics_params> ::core::ops::Index<::core::ops::Range<usize>> for #ident_name #ty_generics #where_clause
413 {
414 type Output = <#from as ::core::ops::Index<::core::ops::Range<usize>>>::Output;
415
416 #[inline]
417 fn index(&self, index: ::core::ops::Range<usize>) -> &Self::Output {
418 self.#field.index(index)
419 }
420 }
421 }
422 }
423 Wrapper::IndexFrom => {
424 quote! {
425 #[automatically_derived]
426 impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeFrom<usize>> for #ident_name #ty_generics #where_clause
427 {
428 type Output = <#from as ::core::ops::Index<::core::ops::RangeFrom<usize>>>::Output;
429
430 #[inline]
431 fn index(&self, index: ::core::ops::RangeFrom<usize>) -> &Self::Output {
432 self.#field.index(index)
433 }
434 }
435 }
436 }
437 Wrapper::IndexTo => {
438 quote! {
439 #[automatically_derived]
440 impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeTo<usize>> for #ident_name #ty_generics #where_clause
441 {
442 type Output = <#from as ::core::ops::Index<::core::ops::RangeTo<usize>>>::Output;
443
444 #[inline]
445 fn index(&self, index: ::core::ops::RangeTo<usize>) -> &Self::Output {
446 self.#field.index(index)
447 }
448 }
449 }
450 }
451 Wrapper::IndexInclusive => {
452 quote! {
453 #[automatically_derived]
454 impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeInclusive<usize>> for #ident_name #ty_generics #where_clause
455 {
456 type Output = <#from as ::core::ops::Index<::core::ops::RangeInclusive<usize>>>::Output;
457
458 #[inline]
459 fn index(&self, index: ::core::ops::RangeInclusive<usize>) -> &Self::Output {
460 self.#field.index(index)
461 }
462 }
463 }
464 }
465 Wrapper::IndexToInclusive => {
466 quote! {
467 #[automatically_derived]
468 impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeToInclusive<usize>> for #ident_name #ty_generics #where_clause
469 {
470 type Output = <#from as ::core::ops::Index<::core::ops::RangeInclusive<usize>>>::Output;
471
472 #[inline]
473 fn index(&self, index: ::core::ops::RangeToInclusive<usize>) -> &Self::Output {
474 self.#field.index(index)
475 }
476 }
477 }
478 }
479 Wrapper::IndexFull => {
480 quote! {
481 #[automatically_derived]
482 impl <#impl_generics_params> ::core::ops::Index<::core::ops::RangeFull> for #ident_name #ty_generics #where_clause
483 {
484 type Output = <#from as ::core::ops::Index<::core::ops::RangeFull>>::Output;
485
486 #[inline]
487 fn index(&self, index: ::core::ops::RangeFull) -> &Self::Output {
488 self.#field.index(index)
489 }
490 }
491 }
492 }
493 Wrapper::Neg => quote! {
494 #[automatically_derived]
495 impl #impl_generics ::core::ops::Neg for #ident_name #ty_generics #where_clause
496 {
497 type Output = Self;
498
499 #[inline]
500 fn neg(self) -> Self {
501 Self { #field: ::core::ops::Neg::neg(self.#field) }
502 }
503 }
504 },
505 Wrapper::Not => quote! {
506 #[automatically_derived]
507 impl #impl_generics ::core::ops::Not for #ident_name #ty_generics #where_clause
508 {
509 type Output = Self;
510
511 #[inline]
512 fn not(self) -> Self {
513 Self { #field: ::core::ops::Not::not(self.#field) }
514 }
515 }
516 },
517 Wrapper::Add => quote! {
518 #[automatically_derived]
519 impl #impl_generics ::core::ops::Add for #ident_name #ty_generics #where_clause
520 {
521 type Output = Self;
522
523 #[inline]
524 fn add(self, rhs: Self) -> Self {
525 Self { #field: ::core::ops::Add::add(self.#field, rhs.#field) }
526 }
527 }
528 },
529 Wrapper::Sub => quote! {
530 #[automatically_derived]
531 impl #impl_generics ::core::ops::Sub for #ident_name #ty_generics #where_clause
532 {
533 type Output = Self;
534
535 #[inline]
536 fn sub(self, rhs: Self) -> Self {
537 Self { #field: ::core::ops::Sub::sub(self.#field, rhs.#field) }
538 }
539 }
540 },
541 Wrapper::Mul => quote! {
542 #[automatically_derived]
543 impl #impl_generics ::core::ops::Mul for #ident_name #ty_generics #where_clause
544 {
545 type Output = Self;
546
547 #[inline]
548 fn mul(self, rhs: Self) -> Self {
549 Self { #field: ::core::ops::Mul::mul(self.#field, rhs.#field) }
550 }
551 }
552 },
553 Wrapper::Div => quote! {
554 #[automatically_derived]
555 impl #impl_generics ::core::ops::Div for #ident_name #ty_generics #where_clause
556 {
557 type Output = Self;
558
559 #[inline]
560 fn div(self, rhs: Self) -> Self {
561 Self { #field: ::core::ops::Div::div(self.#field, rhs.#field) }
562 }
563 }
564 },
565 Wrapper::Rem => quote! {
566 #[automatically_derived]
567 impl #impl_generics ::core::ops::Rem for #ident_name #ty_generics #where_clause
568 {
569 type Output = Self;
570
571 #[inline]
572 fn rem(self, rhs: Self) -> Self {
573 Self { #field: ::core::ops::Rem::rem(self.#field, rhs.#field) }
574 }
575 }
576 },
577 Wrapper::Shl => quote! {
578 #[automatically_derived]
579 impl #impl_generics ::core::ops::Shl for #ident_name #ty_generics #where_clause
580 {
581 type Output = Self;
582
583 #[inline]
584 fn shl(self, rhs: Self) -> Self {
585 Self { #field: ::core::ops::Shl::shl(self.#field, rhs.#field) }
586 }
587 }
588 },
589 Wrapper::Shr => quote! {
590 #[automatically_derived]
591 impl #impl_generics ::core::ops::Shr for #ident_name #ty_generics #where_clause
592 {
593 type Output = Self;
594
595 #[inline]
596 fn shr(self, rhs: Self) -> Self {
597 Self { #field: ::core::ops::Shr::shr(self.#field, rhs.#field) }
598 }
599 }
600 },
601 Wrapper::BitAnd => quote! {
602 #[automatically_derived]
603 impl #impl_generics ::core::ops::BitAnd for #ident_name #ty_generics #where_clause
604 {
605 type Output = Self;
606
607 #[inline]
608 fn bitand(self, rhs: Self) -> Self {
609 Self { #field: ::core::ops::BitAnd::bitand(self.#field, rhs.#field) }
610 }
611 }
612 },
613 Wrapper::BitOr => quote! {
614 #[automatically_derived]
615 impl #impl_generics ::core::ops::BitOr for #ident_name #ty_generics #where_clause
616 {
617 type Output = Self;
618
619 #[inline]
620 fn bitor(self, rhs: Self) -> Self {
621 Self { #field: ::core::ops::BitOr::bitor(self.#field, rhs.#field) }
622 }
623 }
624 },
625 Wrapper::BitXor => quote! {
626 #[automatically_derived]
627 impl #impl_generics ::core::ops::BitXor for #ident_name #ty_generics #where_clause
628 {
629 type Output = Self;
630
631 #[inline]
632 fn bitxor(self, rhs: Self) -> Self {
633 Self { #field: ::core::ops::BitXor::bitxor(self.#field, rhs.#field) }
634 }
635 }
636 },
637 Wrapper::NoRefs |
638 Wrapper::Hex |
639 Wrapper::Exp |
640 Wrapper::NumberFmt |
641 Wrapper::RangeOps |
642 Wrapper::MathOps |
643 Wrapper::BoolOps |
644 Wrapper::BitOps => unreachable!(),
645 }
646 }
647}
648
649impl FromPath for WrapperMut {
650 const IDENT: &'static str = "wrapper_mut";
651 const NO_REFS: Self = Self::NoRefs;
652
653 fn default_set() -> Vec<Self> { vec![WrapperMut::AsMut, WrapperMut::BorrowMut] }
654
655 fn is_not_ref(&self) -> bool { *self != WrapperMut::AsMut && *self != WrapperMut::BorrowMut }
656
657 fn from_path(path: &Path) -> Result<Option<Self>> {
658 path.segments.first().map_or(
659 Err(attr_err!(path.span(), NAME, "must contain at least one identifier", EXAMPLE)),
660 |segment| {
661 Ok(match segment.ident.to_string().as_str() {
662 "NoRefs" => Some(WrapperMut::NoRefs),
663 "DerefMut" => Some(WrapperMut::DerefMut),
664 "AsMut" => Some(WrapperMut::AsMut),
665 "AsSliceMut" => Some(WrapperMut::AsSliceMut),
666 "BorrowMut" => Some(WrapperMut::BorrowMut),
667 "BorrowSliceMut" => Some(WrapperMut::BorrowSliceMut),
668 "IndexMut" => Some(WrapperMut::IndexMut),
669 "IndexRangeMut" => Some(WrapperMut::IndexRangeMut),
670 "IndexFullMut" => Some(WrapperMut::IndexFullMut),
671 "IndexFromMut" => Some(WrapperMut::IndexFromMut),
672 "IndexToMut" => Some(WrapperMut::IndexToMut),
673 "IndexInclusiveMut" => Some(WrapperMut::IndexInclusiveMut),
674 "IndexToInclusiveMut" => Some(WrapperMut::IndexToInclusiveMut),
675 "AddAssign" => Some(WrapperMut::AddAssign),
676 "SubAssign" => Some(WrapperMut::SubAssign),
677 "MulAssign" => Some(WrapperMut::MulAssign),
678 "DivAssign" => Some(WrapperMut::DivAssign),
679 "RemAssign" => Some(WrapperMut::RemAssign),
680 "ShlAssign" => Some(WrapperMut::ShlAssign),
681 "ShrAssign" => Some(WrapperMut::ShrAssign),
682 "BitAndAssign" => Some(WrapperMut::BitAndAssign),
683 "BitOrAssign" => Some(WrapperMut::BitOrAssign),
684 "BitXorAssign" => Some(WrapperMut::BitXorAssign),
685
686 "RangeMut" => Some(WrapperMut::RangeMut),
687 "MathAssign" => Some(WrapperMut::MathAssign),
688 "BoolAssign" => Some(WrapperMut::BoolAssign),
689 "BitAssign" => Some(WrapperMut::BitAssign),
690 _ => None,
691 })
692 },
693 )
694 }
695
696 fn populate(self, list: &mut Vec<Self>) {
697 let exp = match self {
698 WrapperMut::RangeMut => &[
699 WrapperMut::IndexRangeMut,
700 WrapperMut::IndexFromMut,
701 WrapperMut::IndexToMut,
702 WrapperMut::IndexInclusiveMut,
703 WrapperMut::IndexToInclusiveMut,
704 WrapperMut::IndexFullMut,
705 ] as &[_],
706 WrapperMut::MathAssign => &[
707 WrapperMut::AddAssign,
708 WrapperMut::SubAssign,
709 WrapperMut::MulAssign,
710 WrapperMut::DivAssign,
711 WrapperMut::RemAssign,
712 ] as &[_],
713 WrapperMut::BoolAssign => {
714 &[WrapperMut::BitAndAssign, WrapperMut::BitOrAssign, WrapperMut::BitXorAssign]
715 as &[_]
716 }
717 WrapperMut::BitAssign => &[
718 WrapperMut::BitAndAssign,
719 WrapperMut::BitOrAssign,
720 WrapperMut::BitXorAssign,
721 WrapperMut::ShlAssign,
722 WrapperMut::ShrAssign,
723 ],
724 x => {
725 list.push(x);
726 &[] as &[_]
727 }
728 };
729 list.extend(exp)
730 }
731}
732
733impl WrapperMut {
734 pub fn into_token_stream2(
735 self,
736 input: &DeriveInput,
737 _from: &Type,
738 field: &TokenStream2,
739 ) -> TokenStream2 {
740 let impl_generics_params = input.generics.params.clone();
741 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
742 let ident_name = &input.ident;
743 let amplify_crate = get_amplify_crate(input);
744
745 match self {
746 WrapperMut::DerefMut => quote! {
747 #[automatically_derived]
748 impl #impl_generics ::core::ops::DerefMut for #ident_name #ty_generics #where_clause
749 {
750 #[inline]
751 fn deref_mut(&mut self) -> &mut Self::Target {
752 &mut self.#field
753 }
754 }
755 },
756 WrapperMut::AsMut => quote! {
757 #[automatically_derived]
758 impl #impl_generics ::core::convert::AsMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
759 #[inline]
760 fn as_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
761 &mut self.#field
762 }
763 }
764 },
765 WrapperMut::AsSliceMut => quote! {
766 #[automatically_derived]
767 impl #impl_generics AsMut<[u8]> for #ident_name #ty_generics #where_clause
768 {
769 #[inline]
770 fn as_mut(&mut self) -> &mut [u8] {
771 AsMut::<[u8]>::as_mut(&mut self.#field)
772 }
773 }
774 },
775 WrapperMut::BorrowMut => quote! {
776 #[automatically_derived]
777 impl #impl_generics ::core::borrow::BorrowMut<<#ident_name #impl_generics as #amplify_crate::Wrapper>::Inner> for #ident_name #ty_generics #where_clause {
778 #[inline]
779 fn borrow_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
780 &mut self.#field
781 }
782 }
783 },
784 WrapperMut::BorrowSliceMut => quote! {
785 #[automatically_derived]
786 impl #impl_generics ::core::borrow::BorrowMut<[u8]> for #ident_name #ty_generics #where_clause
787 {
788 #[inline]
789 fn borrow_mut(&mut self) -> &mut [u8] {
790 ::core::borrow::BorrowMut::<[u8]>::borrow_mut(&mut self.#field)
791 }
792 }
793 },
794 WrapperMut::IndexMut => {
795 let where_clause = match where_clause {
796 None => quote! { where },
797 Some(_) => quote! { #where_clause },
798 };
799 quote! {
800 #[automatically_derived]
801 impl <#impl_generics_params> ::core::ops::IndexMut<usize> for #ident_name #ty_generics #where_clause
802 {
803 #[inline]
804 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
805 self.as_mut().index_mut(index)
806 }
807 }
808 }
809 }
810 WrapperMut::IndexRangeMut => {
811 quote! {
812 #[automatically_derived]
813 impl <#impl_generics_params> ::core::ops::IndexMut<::core::ops::Range<usize>> for #ident_name #ty_generics #where_clause
814 {
815 #[inline]
816 fn index_mut(&mut self, index: ::core::ops::Range<usize>) -> &mut Self::Output {
817 self.as_mut().index_mut(index)
818 }
819 }
820 }
821 }
822 WrapperMut::IndexFromMut => {
823 quote! {
824 #[automatically_derived]
825 impl <#impl_generics_params> ::core::ops::IndexMut<::core::ops::RangeFrom<usize>> for #ident_name #ty_generics #where_clause
826 {
827 #[inline]
828 fn index_mut(&mut self, index: ::core::ops::RangeFrom<usize>) -> &mut Self::Output {
829 self.as_mut().index_mut(index)
830 }
831 }
832 }
833 }
834 WrapperMut::IndexToMut => {
835 quote! {
836 #[automatically_derived]
837 impl <#impl_generics_params> ::core::ops::IndexMut<::core::ops::RangeTo<usize>> for #ident_name #ty_generics #where_clause
838 {
839 #[inline]
840 fn index_mut(&mut self, index: ::core::ops::RangeTo<usize>) -> &mut Self::Output {
841 self.as_mut().index_mut(index)
842 }
843 }
844 }
845 }
846 WrapperMut::IndexInclusiveMut => {
847 quote! {
848 #[automatically_derived]
849 impl <#impl_generics_params> ::core::ops::IndexMut<::core::ops::RangeInclusive<usize>> for #ident_name #ty_generics #where_clause
850 {
851 #[inline]
852 fn index_mut(&mut self, index: ::core::ops::RangeInclusive<usize>) -> &mut Self::Output {
853 self.as_mut().index_mut(index)
854 }
855 }
856 }
857 }
858 WrapperMut::IndexToInclusiveMut => {
859 quote! {
860 #[automatically_derived]
861 impl <#impl_generics_params> ::core::ops::IndexMut<::core::ops::RangeToInclusive<usize>> for #ident_name #ty_generics #where_clause
862 {
863 #[inline]
864 fn index_mut(&mut self, index: ::core::ops::RangeToInclusive<usize>) -> &mut Self::Output {
865 self.as_mut().index_mut(index)
866 }
867 }
868 }
869 }
870 WrapperMut::IndexFullMut => {
871 quote! {
872 #[automatically_derived]
873 impl <#impl_generics_params> ::core::ops::IndexMut<::core::ops::RangeFull> for #ident_name #ty_generics #where_clause
874 {
875 #[inline]
876 fn index_mut(&mut self, index: ::core::ops::RangeFull) -> &mut Self::Output {
877 self.as_mut().index_mut(index)
878 }
879 }
880 }
881 }
882 WrapperMut::AddAssign => quote! {
883 #[automatically_derived]
884 impl #impl_generics ::core::ops::AddAssign for #ident_name #ty_generics #where_clause
885 {
886 #[inline]
887 fn add_assign(&mut self, rhs: Self) {
888 ::core::ops::AddAssign::add_assign(&mut self.#field, rhs.#field)
889 }
890 }
891 },
892 WrapperMut::SubAssign => quote! {
893 #[automatically_derived]
894 impl #impl_generics ::core::ops::SubAssign for #ident_name #ty_generics #where_clause
895 {
896 #[inline]
897 fn sub_assign(&mut self, rhs: Self) {
898 ::core::ops::SubAssign::sub_assign(&mut self.#field, rhs.#field)
899 }
900 }
901 },
902 WrapperMut::MulAssign => quote! {
903 #[automatically_derived]
904 impl #impl_generics ::core::ops::MulAssign for #ident_name #ty_generics #where_clause
905 {
906 #[inline]
907 fn mul_assign(&mut self, rhs: Self) {
908 ::core::ops::MulAssign::mul_assign(&mut self.#field, rhs.#field)
909 }
910 }
911 },
912 WrapperMut::DivAssign => quote! {
913 #[automatically_derived]
914 impl #impl_generics ::core::ops::DivAssign for #ident_name #ty_generics #where_clause
915 {
916 #[inline]
917 fn div_assign(&mut self, rhs: Self) {
918 ::core::ops::DivAssign::div_assign(&mut self.#field, rhs.#field)
919 }
920 }
921 },
922 WrapperMut::RemAssign => quote! {
923 #[automatically_derived]
924 impl #impl_generics ::core::ops::RemAssign for #ident_name #ty_generics #where_clause
925 {
926 #[inline]
927 fn rem_assign(&mut self, rhs: Self) {
928 ::core::ops::RemAssign::rem_assign(&mut self.#field, rhs.#field)
929 }
930 }
931 },
932 WrapperMut::ShlAssign => quote! {
933 #[automatically_derived]
934 impl #impl_generics ::core::ops::ShlAssign for #ident_name #ty_generics #where_clause
935 {
936 #[inline]
937 fn shl_assign(&mut self, rhs: Self) {
938 ::core::ops::ShlAssign::shl_assign(&mut self.#field, rhs.#field)
939 }
940 }
941 },
942 WrapperMut::ShrAssign => quote! {
943 #[automatically_derived]
944 impl #impl_generics ::core::ops::ShrAssign for #ident_name #ty_generics #where_clause
945 {
946 #[inline]
947 fn shr_assign(&mut self, rhs: Self) {
948 ::core::ops::ShrAssign::shr_assign(&mut self.#field, rhs.#field)
949 }
950 }
951 },
952 WrapperMut::BitAndAssign => quote! {
953 #[automatically_derived]
954 impl #impl_generics ::core::ops::BitAndAssign for #ident_name #ty_generics #where_clause
955 {
956 #[inline]
957 fn bitand_assign(&mut self, rhs: Self) {
958 ::core::ops::BitAndAssign::bitand_assign(&mut self.#field, rhs.#field)
959 }
960 }
961 },
962 WrapperMut::BitOrAssign => quote! {
963 #[automatically_derived]
964 impl #impl_generics ::core::ops::BitOrAssign for #ident_name #ty_generics #where_clause
965 {
966 #[inline]
967 fn bitor_assign(&mut self, rhs: Self) {
968 ::core::ops::BitOrAssign::bitor_assign(&mut self.#field, rhs.#field)
969 }
970 }
971 },
972 WrapperMut::BitXorAssign => quote! {
973 #[automatically_derived]
974 impl #impl_generics ::core::ops::BitXorAssign for #ident_name #ty_generics #where_clause
975 {
976 #[inline]
977 fn bitxor_assign(&mut self, rhs: Self) {
978 ::core::ops::BitXorAssign::bitxor_assign(&mut self.#field, rhs.#field)
979 }
980 }
981 },
982 WrapperMut::NoRefs |
983 WrapperMut::RangeMut |
984 WrapperMut::MathAssign |
985 WrapperMut::BoolAssign |
986 WrapperMut::BitAssign => unreachable!(),
987 }
988 }
989}
990
991pub(crate) fn inner(input: DeriveInput) -> Result<TokenStream2> {
992 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
993 let ident_name = &input.ident;
994 let amplify_crate = get_amplify_crate(&input);
995
996 let (field, from) = get_params(&input)?;
997
998 let wrappers = get_wrappers::<Wrapper>(&input)?;
999 let wrapper_derive = wrappers
1000 .iter()
1001 .map(|w| w.into_token_stream2(&input, &from, &field));
1002
1003 Ok(quote! {
1004 #[automatically_derived]
1005 impl #impl_generics #amplify_crate::Wrapper for #ident_name #ty_generics #where_clause {
1006 type Inner = #from;
1007
1008 #[inline]
1009 fn from_inner(inner: Self::Inner) -> Self {
1010 Self::from(inner)
1011 }
1012
1013 #[inline]
1014 fn as_inner(&self) -> &Self::Inner {
1015 &self.#field
1016 }
1017
1018 #[inline]
1019 fn into_inner(self) -> Self::Inner {
1020 self.#field
1021 }
1022 }
1023
1024 #[automatically_derived]
1025 impl #impl_generics ::core::convert::From<#ident_name #ty_generics> for #from #where_clause {
1026 #[inline]
1027 fn from(wrapped: #ident_name #ty_generics) -> Self {
1028 wrapped.#field
1029 }
1030 }
1031
1032 #( #wrapper_derive )*
1033 })
1034}
1035
1036pub(crate) fn inner_mut(input: DeriveInput) -> Result<TokenStream2> {
1037 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
1038 let ident_name = &input.ident;
1039 let amplify_crate = get_amplify_crate(&input);
1040
1041 let (field, from) = get_params(&input)?;
1042
1043 let wrappers = get_wrappers::<WrapperMut>(&input)?;
1044 let wrapper_derive = wrappers
1045 .iter()
1046 .map(|w| w.into_token_stream2(&input, &from, &field));
1047
1048 Ok(quote! {
1049 #[automatically_derived]
1050 impl #impl_generics #amplify_crate::WrapperMut for #ident_name #ty_generics #where_clause {
1051 #[inline]
1052 fn as_inner_mut(&mut self) -> &mut <Self as #amplify_crate::Wrapper>::Inner {
1053 &mut self.#field
1054 }
1055 }
1056
1057 #( #wrapper_derive )*
1058 })
1059}
1060
1061fn get_params(input: &DeriveInput) -> Result<(TokenStream2, Type)> {
1062 let data = match input.data {
1063 Data::Struct(ref data) => data,
1064 Data::Enum(_) => {
1065 return Err(Error::new_spanned(input, "Deriving wrapper is not supported in enums"));
1066 }
1067 Data::Union(_) => {
1069 return Err(Error::new_spanned(input, "Deriving wrapper is not supported in unions"));
1070 }
1071 };
1072
1073 let field;
1074 let mut from;
1075 match data.fields {
1076 Fields::Named(ref fields) => {
1077 let mut source = None;
1078 from = fields.named[0].ty.clone();
1079 for field in &fields.named {
1080 for attr in &field.attrs {
1081 if attr.path.is_ident("wrap") {
1082 if source.is_some() {
1083 return Err(Error::new_spanned(
1084 attr,
1085 "Only a single field may be wrapped",
1086 ));
1087 }
1088 source = Some(field.ident.clone().expect("we know it's named"));
1089 from = field.ty.clone();
1090 }
1091 }
1092 }
1093 if source.is_none() && fields.named.len() > 1 {
1094 return Err(Error::new_spanned(
1095 fields,
1096 "When the structure has multiple fields you must point out the one you will \
1097 wrap by using `#[wrap]` attribute",
1098 ));
1099 }
1100 let source = source
1101 .unwrap_or_else(|| fields.named[0].ident.clone().expect("we know it's named"));
1102 field = quote! { #source };
1103 }
1104 Fields::Unnamed(ref fields) => {
1105 let mut source = None;
1106 from = fields.unnamed[0].ty.clone();
1107 for (index, field) in fields.unnamed.iter().enumerate() {
1108 for attr in &field.attrs {
1109 if attr.path.is_ident("wrap") {
1110 if source.is_some() {
1111 return Err(Error::new_spanned(
1112 attr,
1113 "Only a single field may be wrapped",
1114 ));
1115 }
1116 let i = Index::from(index);
1117 source = Some(quote! { #i });
1118 from = field.ty.clone();
1119 }
1120 }
1121 }
1122 if source.is_none() && fields.unnamed.len() > 1 {
1123 return Err(Error::new_spanned(
1124 fields,
1125 "When the structure has multiple fields you must point out the one you will \
1126 wrap by using `#[wrap]` attribute",
1127 ));
1128 }
1129 field = source.unwrap_or(quote! { 0 });
1130 }
1131 Fields::Unit => {
1132 return Err(Error::new_spanned(
1133 input,
1134 "Deriving wrapper is meaningless for unit structs",
1135 ));
1136 }
1137 };
1138 Ok((field, from))
1139}
1140
1141fn get_wrappers<T: FromPath>(input: &DeriveInput) -> Result<Vec<T>> {
1142 let mut wrappers = T::default_set();
1143 const WRAPPER_DERIVE_ERR: &str = "Wrapper attributes must be in a form of type list";
1144 for attr in input
1145 .attrs
1146 .iter()
1147 .filter(|attr| attr.path.is_ident(T::IDENT))
1148 {
1149 match attr
1150 .parse_meta()
1151 .map_err(|_| attr_err!(attr, WRAPPER_DERIVE_ERR))?
1152 {
1153 Meta::List(MetaList { nested, .. }) => {
1154 for meta in nested {
1155 match meta {
1156 NestedMeta::Meta(Meta::Path(path)) => {
1157 T::from_path(&path)?
1158 .ok_or_else(|| attr_err!(path, "Unrecognized wrapper parameter"))?
1159 .populate(&mut wrappers);
1160 }
1161 _ => return Err(attr_err!(meta, WRAPPER_DERIVE_ERR)),
1162 }
1163 }
1164 }
1165 _ => return Err(attr_err!(attr, WRAPPER_DERIVE_ERR)),
1166 }
1167 }
1168 if wrappers.contains(&T::NO_REFS) {
1169 wrappers = wrappers.into_iter().filter(T::is_not_ref).collect();
1170 }
1171 Ok(wrappers)
1172}