result_like_derive/
lib.rs

1#![recursion_limit = "512"]
2
3extern crate proc_macro;
4
5use pmutil::{Quote, ToTokensExt, smart_quote};
6use quote::{ToTokens, quote};
7use syn::{
8    Data, DataEnum, DeriveInput, Field, Generics, Ident, WhereClause, WherePredicate,
9    punctuated::Punctuated, token::Comma,
10};
11
12#[proc_macro_derive(BoolLike)]
13pub fn bool_like(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
14    let input: DeriveInput = syn::parse(input).expect("failed to parse derive input");
15
16    let data = match input.data {
17        Data::Enum(ref data) => data,
18        _ => panic!("`BoolLike` can be applied only on enums"),
19    };
20
21    expand(&input, BoolLike, data)
22}
23
24#[proc_macro_derive(OptionLike)]
25pub fn option_like(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
26    let input: DeriveInput = syn::parse(input).expect("failed to parse derive input");
27
28    let data = match input.data {
29        Data::Enum(ref data) => data,
30        _ => panic!("`OptionLike` can be applied only on enums"),
31    };
32
33    expand(&input, OptionLike, data)
34}
35
36#[proc_macro_derive(ResultLike)]
37pub fn result_like(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
38    let input: DeriveInput = syn::parse(input).expect("failed to parse derive input");
39
40    let data = match input.data {
41        Data::Enum(ref data) => data,
42        _ => panic!("`ResultLike` can be applied only on enums"),
43    };
44
45    expand(&input, ResultLike, data)
46}
47
48#[derive(Clone, Copy, PartialEq, Eq)]
49enum VariantFieldsType {
50    Unnamed,
51    Unit,
52}
53
54impl VariantFieldsType {
55    fn matches(self, fields: &syn::Fields) -> bool {
56        #[allow(clippy::match_like_matches_macro)]
57        match (self, fields) {
58            (VariantFieldsType::Unnamed, syn::Fields::Unnamed(_)) => true,
59            (VariantFieldsType::Unit, syn::Fields::Unit) => true,
60            _ => false,
61        }
62    }
63}
64
65trait LikeTrait {
66    fn data(&self) -> LikeData;
67    fn quote_impl(&self, args: ImplArgs) -> Quote;
68}
69
70struct ImplArgs<'a> {
71    typ: &'a Ident,
72    generics: &'a Generics,
73    primary: &'a Ident,
74    secondary: &'a Ident,
75    primary_inner: Option<&'a Punctuated<Field, Comma>>,
76    secondary_inner: Option<&'a Punctuated<Field, Comma>>,
77}
78
79impl<'a> ImplArgs<'a> {
80    fn split_for_impl(
81        &self,
82    ) -> (
83        Generics,
84        Generics,
85        Option<&WhereClause>,
86        Punctuated<WherePredicate, Comma>,
87    ) {
88        let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl();
89        let impl_generics =
90            syn::parse2::<Generics>(impl_generics.dump()).expect("generics to generics");
91        let ty_generics =
92            syn::parse2::<Generics>(ty_generics.dump()).expect("generics to generics");
93        let where_predicates = where_clause.map_or(
94            WhereClause {
95                where_token: Default::default(),
96                predicates: Default::default(),
97            }
98            .predicates,
99            |w| w.predicates.clone(),
100        );
101        (impl_generics, ty_generics, where_clause, where_predicates)
102    }
103}
104
105struct LikeData {
106    name: String,
107    fields: (VariantFieldsType, VariantFieldsType),
108}
109
110fn expand(
111    input: &DeriveInput,
112    like_trait: impl LikeTrait,
113    data: &DataEnum,
114) -> proc_macro::TokenStream {
115    let typ = &input.ident;
116    let like = like_trait.data();
117
118    assert_eq!(
119        data.variants.len(),
120        2,
121        "{} expects 2 variants but {} variant(s) given",
122        &like.name,
123        data.variants.len()
124    );
125
126    let (primary_variant, secondary_variant) = {
127        let mut iter = data.variants.iter();
128        (iter.next().unwrap(), iter.next().unwrap())
129    };
130
131    assert!(like.fields.0.matches(&primary_variant.fields));
132    assert!(like.fields.1.matches(&secondary_variant.fields));
133
134    let primary = &primary_variant.ident;
135    let secondary = &secondary_variant.ident;
136
137    let primary_inner = match &primary_variant.fields {
138        syn::Fields::Unnamed(syn::FieldsUnnamed { unnamed, .. }) => Some(unnamed),
139        _ => None,
140    };
141    let secondary_inner = match &secondary_variant.fields {
142        syn::Fields::Unnamed(syn::FieldsUnnamed { unnamed, .. }) => Some(unnamed),
143        _ => None,
144    };
145
146    let like_impl = like_trait.quote_impl(ImplArgs {
147        typ,
148        generics: &input.generics,
149        primary,
150        secondary,
151        primary_inner,
152        secondary_inner,
153    });
154
155    like_impl.into()
156}
157
158struct BoolLike;
159
160impl LikeTrait for BoolLike {
161    fn data(&self) -> LikeData {
162        LikeData {
163            name: "BoolLike".to_owned(),
164            fields: (VariantFieldsType::Unit, VariantFieldsType::Unit),
165        }
166    }
167
168    fn quote_impl(&self, args: ImplArgs) -> Quote {
169        let ImplArgs {
170            typ,
171            primary,
172            secondary,
173            ..
174        } = args;
175        Quote::new_call_site().quote_with(smart_quote!(
176            Vars {
177                Type: &typ,
178                Primary: primary,
179                Secondary: secondary,
180            },
181            {
182                impl Type {
183                    pub const fn to_bool(self) -> bool {
184                        match self {
185                            Type::Primary => true,
186                            Type::Secondary => false,
187                        }
188                    }
189                    pub const fn from_bool(value: bool) -> Self {
190                        if value {
191                            Type::Primary
192                        } else {
193                            Type::Secondary
194                        }
195                    }
196                    pub fn then_some<T>(self, t: T) -> Option<T> {
197                        self.to_bool().then_some(t)
198                    }
199                    pub fn then<T, F>(self, f: F) -> Option<T>
200                    where
201                        F: FnOnce() -> T,
202                    {
203                        self.to_bool().then(f)
204                    }
205                }
206                impl From<bool> for Type {
207                    fn from(value: bool) -> Self {
208                        Self::from_bool(value)
209                    }
210                }
211                impl From<Type> for bool {
212                    fn from(value: Type) -> Self {
213                        value.to_bool()
214                    }
215                }
216            }
217        ))
218    }
219}
220
221struct OptionLike;
222
223impl LikeTrait for OptionLike {
224    fn data(&self) -> LikeData {
225        LikeData {
226            name: "OptionLike".to_owned(),
227            fields: (VariantFieldsType::Unnamed, VariantFieldsType::Unit),
228        }
229    }
230
231    fn quote_impl(&self, args: ImplArgs) -> Quote {
232        let ImplArgs {
233            typ,
234            primary,
235            secondary,
236            primary_inner,
237            ..
238        } = args;
239        let primary_inner = primary_inner.expect("primary_inner always exists for OptionLike");
240        let (impl_generics, ty_generics, where_clause, where_predicates) = args.split_for_impl();
241        let mut option_impl = Quote::new_call_site().quote_with(smart_quote!(
242            Vars {
243                Type: &typ,
244                impl_generics: &impl_generics,
245                ty_generics: &ty_generics,
246                where_clause: &where_clause,
247                Primary: primary,
248                Secondary: secondary,
249                PrimaryValue: primary_inner,
250            },
251            {
252                impl impl_generics result_like::OptionLike for Type ty_generics where_clause {
253                    type SomeType = PrimaryValue;
254                }
255                impl impl_generics Type ty_generics where_clause {
256                    #[inline]
257                    pub fn from_option(option: Option<PrimaryValue>) -> Self {
258                        match option {
259                            Some(v) => Type::Primary(v),
260                            None => Type::Secondary,
261                        }
262                    }
263
264                    #[inline]
265                    pub fn into_option(self) -> Option<PrimaryValue> {
266                        match self {
267                            Type::Primary(v) => Some(v),
268                            Type::Secondary => None,
269                        }
270                    }
271
272                    #[inline]
273                    pub fn as_option(&self) -> Option<&PrimaryValue> {
274                        match self {
275                            Type::Primary(v) => Some(v),
276                            Type::Secondary => None,
277                        }
278                    }
279
280                    #[inline]
281                    pub fn as_option_mut(&mut self) -> Option<&mut PrimaryValue> {
282                        match self {
283                            Type::Primary(v) => Some(v),
284                            Type::Secondary => None,
285                        }
286                    }
287
288                    #[inline]
289                    pub fn expect(self, msg: &str) -> PrimaryValue where {
290                        self.into_option().expect(msg)
291                    }
292
293                    #[inline]
294                    pub fn unwrap(self) -> PrimaryValue {
295                        self.into_option().unwrap()
296                    }
297
298                    #[inline]
299                    pub fn unwrap_or(self, default: PrimaryValue) -> PrimaryValue {
300                        self.into_option().unwrap_or(default)
301                    }
302
303                    #[inline]
304                    pub fn unwrap_or_else<_Function: FnOnce() -> PrimaryValue>(self, f: _Function) -> PrimaryValue {
305                        self.into_option().unwrap_or_else(f)
306                    }
307
308                    #[inline]
309                    pub fn ok_or<_Error>(self, err: _Error) -> Result<PrimaryValue, _Error> {
310                        self.into_option().ok_or(err)
311                    }
312
313                    #[inline]
314                    pub fn ok_or_else<_Error, _Function: FnOnce() -> _Error>(self, err: _Function) -> Result<PrimaryValue, _Error> {
315                        self.into_option().ok_or_else(err)
316                    }
317
318                    #[inline]
319                    pub fn filter<P: FnOnce(&PrimaryValue) -> bool>(self, predicate: P) -> Self {
320                        Self::from_option(self.into_option().filter(predicate))
321                    }
322
323                    #[inline]
324                    pub fn or(self, optb: Self) -> Self {
325                        Self::from_option(self.into_option().or(optb.into_option()))
326                    }
327
328                    #[inline]
329                    pub fn or_else<_Function: FnOnce() -> Self>(self, f: _Function) -> Self {
330                        Self::from_option(self.into_option().or_else(|| f().into_option()))
331                    }
332
333                    #[inline]
334                    pub fn map_or<_Other, _Function: FnOnce(PrimaryValue) -> _Other>(
335                        self,
336                        default: _Other,
337                        f: _Function,
338                    ) -> _Other {
339                        self.into_option().map_or(default, f)
340                    }
341
342                    #[inline]
343                    pub fn xor(self, optb: Self) -> Self {
344                        Self::from_option(self.into_option().xor(optb.into_option()))
345                    }
346
347                    #[inline]
348                    pub fn get_or_insert(&mut self, v: PrimaryValue) -> &mut PrimaryValue {
349                        self.get_or_insert_with(|| v)
350                    }
351
352                    #[inline]
353                    pub fn get_or_insert_with<_Function: FnOnce() -> PrimaryValue>(&mut self, f: _Function) -> &mut PrimaryValue {
354                        if let Type::Secondary = *self {
355                            *self = Type::Primary(f());
356                        }
357
358                        match self {
359                            Type::Primary(v) => v,
360                            Type::Secondary => unsafe { core::hint::unreachable_unchecked() },
361                        }
362                    }
363
364                    #[inline]
365                    pub fn replace(&mut self, value: PrimaryValue) -> Self {
366                        core::mem::replace(self, Type::Primary(value))
367                    }
368                }
369
370                impl impl_generics From<Option<PrimaryValue>> for Type ty_generics where_clause {
371                    fn from(value: Option<PrimaryValue>) -> Self {
372                        Self::from_option(value)
373                    }
374                }
375
376                impl impl_generics From<Type ty_generics> for Option<PrimaryValue> where_clause {
377                    fn from(value: Type ty_generics) -> Self {
378                        value.into_option()
379                    }
380                }
381
382                impl impl_generics From<PrimaryValue> for Type ty_generics where_clause {
383                    #[inline]
384                    fn from(value: PrimaryValue) -> Self {
385                        Type::Primary(value)
386                    }
387                }
388
389                impl impl_generics Default for Type ty_generics {
390                    #[inline]
391                    fn default() -> Self {
392                        Type::Secondary
393                    }
394                }
395
396                impl impl_generics IntoIterator for Type ty_generics where_clause {
397                    type Item = PrimaryValue;
398                    type IntoIter = core::option::IntoIter<PrimaryValue>;
399
400                    #[inline]
401                    fn into_iter(self) -> core::option::IntoIter<PrimaryValue> {
402                        self.into_option().into_iter()
403                    }
404                }
405            }
406        ));
407        if !ty_generics.params.is_empty() {
408            option_impl = option_impl.quote_with(smart_quote!(
409                Vars {
410                    Type: &typ,
411                    impl_generics: &impl_generics,
412                    ty_generics: &ty_generics,
413                    where_predicates: &where_predicates,
414                    where_clause: &where_clause,
415                    Primary: primary,
416                    Secondary: secondary,
417                    PrimaryValue: primary_inner,
418                },
419                {
420                    impl impl_generics Type ty_generics where_clause {
421                        #[inline]
422                        pub fn as_ref(&self) -> Type<&PrimaryValue> {
423                            match self {
424                                Type::Primary(x) => Type::Primary(x),
425                                Type::Secondary => Type::Secondary,
426                            }
427                        }
428
429                        #[inline]
430                        pub fn as_mut(&mut self) -> Type<&mut PrimaryValue> {
431                            match self {
432                                Type::Primary(x) => Type::Primary(x),
433                                Type::Secondary => Type::Secondary,
434                            }
435                        }
436
437                        // as_pin_ref
438                        // as_pin_mut
439
440                        #[inline]
441                        pub fn map<_Other, _Function: FnOnce(PrimaryValue) -> _Other>(self, f: _Function) -> Type<_Other> {
442                            match self {
443                                Type::Primary(x) => Type::Primary(f(x)),
444                                Type::Secondary => Type::Secondary,
445                            }
446                        }
447
448                        #[inline]
449                        pub fn map_or_else<_Other, _Default: FnOnce() -> _Other, _Function: FnOnce(PrimaryValue) -> _Other>(
450                            self,
451                            default: _Default,
452                            f: _Function,
453                        ) -> _Other {
454                            self.into_option().map_or_else(default, f)
455                        }
456
457                        pub fn iter(&self) -> impl core::iter::Iterator<Item = &PrimaryValue> {
458                            self.as_option().into_iter()
459                        }
460
461                        pub fn iter_mut(&mut self) -> impl core::iter::Iterator<Item = &mut PrimaryValue> {
462                            self.as_option_mut().into_iter()
463                        }
464
465                        #[inline]
466                        pub fn and<_Other>(self, optb: Type<_Other>) -> Type<_Other> {
467                            match self {
468                                Type::Primary(_) => optb,
469                                Type::Secondary => Type::Secondary,
470                            }
471                        }
472
473                        #[inline]
474                        pub fn and_then<_Other, _Function: FnOnce(PrimaryValue) -> Type<_Other>>(self, f: _Function) -> Type<_Other> {
475                            match self {
476                                Type::Primary(x) => f(x),
477                                Type::Secondary => Type::Secondary,
478                            }
479                        }
480
481                        pub fn zip<_Other>(self, other: Type<_Other>) -> Type<(PrimaryValue, _Other)> {
482                            Type::from_option(self.into_option().zip(other.into_option()))
483                        }
484
485                        // pub fn zip_with<_Other, _Function, _Result>(self, other: Type<_Other>, f: _Function) -> Type<_Result>
486                        // where
487                        //     _Function: FnOnce(PrimaryValue, _Other) -> _Result,
488                        // {
489                        //     Type::from_option(self.into_option().zip_with(other.into_option(), f))
490                        // }
491
492                        #[inline]
493                        pub fn take(&mut self) -> Self where where_predicates PrimaryValue: Default {
494                            core::mem::take(self)
495                        }
496
497                        #[inline]
498                        pub fn unwrap_or_default(self) -> PrimaryValue where where_predicates PrimaryValue: Default {
499                            self.into_option().unwrap_or_default()
500                        }
501                    }
502
503                    impl impl_generics Copy for Type ty_generics where where_predicates PrimaryValue: Copy {}
504
505                    impl impl_generics Clone for Type ty_generics where where_predicates PrimaryValue: Clone {
506                        #[inline]
507                        fn clone(&self) -> Self {
508                            match self {
509                                Type::Primary(x) => Type::Primary(x.clone()),
510                                Type::Secondary => Type::Secondary,
511                            }
512                        }
513
514                        #[inline]
515                        fn clone_from(&mut self, source: &Self) {
516                            match (self, source) {
517                                (Type::Primary(to), Type::Primary(from)) => to.clone_from(from),
518                                (to, from) => *to = from.clone(),
519                            }
520                        }
521                    }
522
523                    impl impl_generics Type<&PrimaryValue> where where_predicates PrimaryValue: Copy {
524                        pub fn copied(self) -> Type<PrimaryValue> {
525                            self.map(|&t| t)
526                        }
527                    }
528
529                    impl impl_generics Type<&mut PrimaryValue> where where_predicates PrimaryValue: Copy {
530                        pub fn copied(self) -> Type<PrimaryValue> {
531                            self.map(|&mut t| t)
532                        }
533                    }
534
535                    impl impl_generics Type<&PrimaryValue> where where_predicates PrimaryValue: Clone {
536                        pub fn cloned(self) -> Type<PrimaryValue> {
537                            self.map(|t| t.clone())
538                        }
539                    }
540
541                    impl impl_generics Type<&mut PrimaryValue> where where_predicates PrimaryValue: Clone {
542                        pub fn cloned(self) -> Type<PrimaryValue> {
543                            self.map(|t| t.clone())
544                        }
545                    }
546
547                    // impl<T: fmt::Debug> Type<T>
548                    // expect_none
549                    // unwrap_none
550
551                    impl impl_generics Type<PrimaryValue> where where_predicates PrimaryValue: core::ops::Deref {
552                        pub fn as_deref(&self) -> Type<&PrimaryValue::Target> {
553                            self.as_ref().map(|t| t.deref())
554                        }
555                    }
556
557                    impl<PrimaryValue: core::ops::DerefMut> Type<PrimaryValue> {
558                        pub fn as_deref_mut(&mut self) -> Type<&mut PrimaryValue::Target> {
559                            self.as_mut().map(|t| t.deref_mut())
560                        }
561                    }
562
563                    impl<PrimaryValue, _Error> Type<Result<PrimaryValue, _Error>> {
564                        #[inline]
565                        pub fn transpose(self) -> Result<Type<PrimaryValue>, _Error> {
566                            self.into_option()
567                                .transpose()
568                                .map(|op| Type::from_option(op))
569                        }
570                    }
571
572                    // TODO: result-like
573
574                    // impl<'a, PrimaryValue> IntoIterator for &'a Type<PrimaryValue> {
575                    //     type Item = &'a PrimaryValue;
576                    //     type IntoIter = core::option::Iter<'a, PrimaryValue>;
577
578                    //     fn into_iter(self) -> core::option::Iter<'a, PrimaryValue> {
579                    //         self.as_option().iter()
580                    //     }
581                    // }
582
583                    // impl<'a, T> IntoIterator for &'a mut Self {
584                    //     type Item = &'a mut T;
585                    //     type IntoIter = core::option::IterMut<'a, T>;
586
587                    //     fn into_iter(self) -> core::option::IterMut<'a, T> {
588                    //         self.iter_mut()
589                    //     }
590                    // }
591
592                    // impl impl_generics From ty_generics  for Type ty_generics where_clause {
593                    //     fn from(val: PrimaryValue) -> Self {
594                    //         Type::Primary(val)
595                    //     }
596                    // }
597
598                    // impl<'a, T> From<&'a Type<T>> for Type<&'a T> {
599                    //     fn from(o: &'a Type<T>) -> Type<&'a T> {
600                    //         o.as_ref()
601                    //     }
602                    // }
603
604                    // impl<'a, T> From<&'a mut Type<T>> for Type<&'a mut T> {
605                    //     fn from(o: &'a mut Type<T>) -> Type<&'a mut T> {
606                    //         o.as_mut()
607                    //     }
608                    // }
609                }
610            ));
611        }
612        option_impl
613    }
614}
615
616struct ResultLike;
617
618impl LikeTrait for ResultLike {
619    fn data(&self) -> LikeData {
620        LikeData {
621            name: "ResultLike".to_owned(),
622            fields: (VariantFieldsType::Unnamed, VariantFieldsType::Unnamed),
623        }
624    }
625
626    fn quote_impl(&self, args: ImplArgs) -> Quote {
627        let ImplArgs {
628            typ,
629            primary,
630            secondary,
631            primary_inner,
632            secondary_inner,
633            ..
634        } = args;
635        let primary_inner = primary_inner.expect("primary_inner always exists for ResultLike");
636        let secondary_inner =
637            secondary_inner.expect("secondary_inner always exists for ResultLike");
638        let (impl_generics, ty_generics, where_clause, where_predicates) = args.split_for_impl();
639        let mut result_impl = Quote::new_call_site().quote_with(smart_quote!(
640            Vars {
641                Type: &typ,
642                impl_generics: &impl_generics,
643                ty_generics: &ty_generics,
644                where_predicates: &where_predicates,
645                where_clause: &where_clause,
646                Primary: primary,
647                Secondary: secondary,
648                T: primary_inner,
649                E: secondary_inner,
650            },
651            {
652                impl impl_generics result_like::ResultLike for Type ty_generics where_clause {
653                    type OkType = T;
654                    type ErrType = E;
655                }
656                impl impl_generics Type ty_generics where_clause {
657                    #[inline]
658                    pub fn from_result(result: Result<T, E>) -> Self {
659                        match result {
660                            Ok(v) => Type::Primary(v),
661                            Err(e) => Type::Secondary(e),
662                        }
663                    }
664
665                    #[inline]
666                    pub fn into_result(self) -> Result<T, E> {
667                        match self {
668                            Type::Primary(v) => Ok(v),
669                            Type::Secondary(e) => Err(e),
670                        }
671                    }
672
673                    #[inline]
674                    pub fn as_result(&self) -> Result<&T, &E> {
675                        match self {
676                            Type::Primary(x) => Ok(x),
677                            Type::Secondary(x) => Err(x),
678                        }
679                    }
680
681                    #[inline]
682                    pub fn as_result_mut(&mut self) -> Result<&mut T, &mut E> {
683                        match self {
684                            Type::Primary(x) => Ok(x),
685                            Type::Secondary(x) => Err(x),
686                        }
687                    }
688
689
690                    #[inline]
691                    pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
692                        match self {
693                            Type::Primary(t) => f(t),
694                            Type::Secondary(_) => default,
695                        }
696                    }
697
698                    #[inline]
699                    pub fn unwrap_or(self, optb: T) -> T {
700                        self.into_result().unwrap_or(optb)
701                    }
702
703                    #[inline]
704                    pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
705                        self.into_result().unwrap_or_else(op)
706                    }
707                }
708
709                impl impl_generics From<Result<T, E>> for Type ty_generics where_clause {
710                    fn from(value: Result<T, E>) -> Self {
711                        Self::from_result(value)
712                    }
713                }
714
715                impl impl_generics From<Type ty_generics> for Result<T, E> where_clause {
716                    fn from(value: Type ty_generics) -> Self {
717                        value.into_result()
718                    }
719                }
720
721                impl impl_generics Type ty_generics where where_predicates E: core::fmt::Debug {
722                    #[inline]
723                    pub fn expect(self, msg: &str) -> T {
724                        self.into_result().expect(msg)
725                    }
726
727                    #[inline]
728                    pub fn unwrap(self) -> T {
729                        self.into_result().unwrap()
730                    }
731                }
732
733                impl impl_generics Type ty_generics where where_predicates T: core::fmt::Debug {
734                    // #[inline]
735                    // pub fn expect_err(self, msg: &str) -> E {
736                    //     self.into_result().expect_err(msg)
737                    // }
738
739                    #[inline]
740                    pub fn unwrap_err(self) -> E {
741                        self.into_result().unwrap_err()
742                    }
743                }
744
745                // into_ok
746
747                impl impl_generics IntoIterator for Type ty_generics {
748                    type Item = T;
749                    type IntoIter = core::result::IntoIter<T>;
750
751                    #[inline]
752                    fn into_iter(self) -> core::result::IntoIter<T> {
753                        self.into_result().into_iter()
754                    }
755                }
756            }
757        ));
758        let param_symbols: Vec<_> = ty_generics
759            .params
760            .iter()
761            .filter_map(|p| match p {
762                syn::GenericParam::Type(type_param) => Some(type_param.ident.to_string()),
763                _ => None,
764            })
765            .collect();
766        let primary_is_generic = primary_inner
767            .iter()
768            .next()
769            .is_some_and(|f| param_symbols.contains(&f.ty.to_token_stream().to_string()));
770        let secondary_is_generic = secondary_inner
771            .iter()
772            .next()
773            .is_some_and(|f| param_symbols.contains(&f.ty.to_token_stream().to_string()));
774        let everything_is_generic = primary_is_generic && secondary_is_generic;
775
776        // println!(
777        //     "flags {:?}  {} {} {}",
778        //     param_symbols, primary_is_generic, secondary_is_generic, everything_is_generic
779        // );
780
781        if primary_is_generic {
782            result_impl = result_impl.quote_with(smart_quote!(
783                Vars {
784                    Type: &typ,
785                    impl_generics: &impl_generics,
786                    ty_generics: &ty_generics,
787                    where_predicates: &where_predicates,
788                    where_clause: &where_clause,
789                    Primary: primary,
790                    Secondary: secondary,
791                    T: primary_inner,
792                    E: secondary_inner,
793                    GenericE: if secondary_is_generic { Some(secondary_inner) } else { None },
794                },
795                {
796                    impl impl_generics Type ty_generics where_clause {
797                        #[inline]
798                        pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Type<U, GenericE> {
799                            match self {
800                                Type::Primary(t) => Type::Primary(op(t)),
801                                Type::Secondary(e) => Type::Secondary(e),
802                            }
803                        }
804                        #[inline]
805                        pub fn map_or_else<U, M: FnOnce(T) -> U, F: FnOnce(E) -> U>(
806                            self,
807                            fallback: F,
808                            map: M,
809                        ) -> U {
810                            self.map(map).unwrap_or_else(fallback)
811                        }
812                        #[inline]
813                        pub fn and<U>(self, res: Type<U, GenericE>) -> Type<U, GenericE> {
814                            match self {
815                                Type::Primary(_) => res,
816                                Type::Secondary(e) => Type::Secondary(e),
817                            }
818                        }
819                        #[inline]
820                        pub fn and_then<U, F: FnOnce(T) -> Type<U, GenericE>>(self, op: F) -> Type<U, GenericE> {
821                            match self {
822                                Type::Primary(t) => op(t),
823                                Type::Secondary(e) => Type::Secondary(e),
824                            }
825                        }
826                    }
827
828                    impl impl_generics Type ty_generics where where_predicates T: Default {
829                        #[inline]
830                        pub fn unwrap_or_default(self) -> T {
831                            self.into_result().unwrap_or_default()
832                        }
833                    }
834
835                    impl impl_generics Type<&T, GenericE> where where_predicates T: Copy {
836                        pub fn copied(self) -> Type ty_generics {
837                            self.map(|&t| t)
838                        }
839                    }
840                    impl impl_generics Type<&mut T, GenericE> where where_predicates T: Copy {
841                        pub fn copied(self) -> Type ty_generics {
842                            self.map(|&mut t| t)
843                        }
844                    }
845
846                    impl impl_generics Type<&T, GenericE> where where_predicates T: Clone {
847                        pub fn cloned(self) -> Type ty_generics {
848                            self.map(|t| t.clone())
849                        }
850                    }
851                    impl impl_generics Type<&mut T, GenericE> where where_predicates T: Clone {
852                        pub fn cloned(self) -> Type ty_generics {
853                            self.map(|t| t.clone())
854                        }
855                    }
856
857                    impl impl_generics Type<Option<T>, GenericE> {
858                        #[inline]
859                        pub fn transpose(self) -> Option<Type<T, GenericE>> {
860                            self.into_result()
861                                .transpose()
862                                .map(|r| Type::from_result(r))
863                        }
864                    }
865                }
866            ));
867        }
868
869        if secondary_is_generic {
870            result_impl = result_impl.quote_with(smart_quote!(
871                Vars {
872                    Type: &typ,
873                    impl_generics: &impl_generics,
874                    ty_generics: &ty_generics,
875                    // where_predicates: &where_predicates,
876                    where_clause: &where_clause,
877                    Primary: primary,
878                    Secondary: secondary,
879                    E: secondary_inner,
880                    GenericT: if primary_is_generic { Some(quote!(#primary_inner ,)) } else { None },
881                },
882                {
883                    impl impl_generics Type ty_generics where_clause {
884                        #[inline]
885                        pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Type<GenericT F> {
886                            match self {
887                                Type::Primary(t) => Type::Primary(t),
888                                Type::Secondary(e) => Type::Secondary(op(e)),
889                            }
890                        }
891
892                        #[inline]
893                        pub fn or<F>(self, res: Type<GenericT F>) -> Type<GenericT F> {
894                            match self {
895                                Type::Primary(v) => Type::Primary(v),
896                                Type::Secondary(_) => res,
897                            }
898                        }
899                        #[inline]
900                        pub fn or_else<F, O: FnOnce(E) -> Type<GenericT F>>(self, op: O) -> Type<GenericT F> {
901                            match self {
902                                Type::Primary(t) => Type::Primary(t),
903                                Type::Secondary(e) => op(e),
904                            }
905                        }
906                    }
907                }
908            ));
909        }
910
911        if everything_is_generic {
912            result_impl = result_impl.quote_with(smart_quote!(
913                Vars {
914                    Type: &typ,
915                    impl_generics: &impl_generics,
916                    ty_generics: &ty_generics,
917                    where_predicates: &where_predicates,
918                    where_clause: &where_clause,
919                    Primary: primary,
920                    Secondary: secondary,
921                    T: primary_inner,
922                    E: secondary_inner,
923                },
924                {
925                impl impl_generics Type ty_generics where_clause {
926                    // contains
927                    // contains_err
928
929                    #[inline]
930                    pub fn as_ref(&self) -> Type<&T, &E> {
931                        match self {
932                            Type::Primary(x) => Type::Primary(x),
933                            Type::Secondary(x) => Type::Secondary(x),
934                        }
935                    }
936
937                    #[inline]
938                    pub fn as_mut(&mut self) -> Type<&mut T, &mut E> {
939                        match self {
940                            Type::Primary(x) => Type::Primary(x),
941                            Type::Secondary(x) => Type::Secondary(x),
942                        }
943                    }
944
945                    // iter
946                    // iter_mut
947                }
948
949                impl impl_generics Copy for Type ty_generics where where_predicates T: Copy, E: Copy { }
950                impl impl_generics Clone for Type ty_generics where where_predicates T: Clone, E: Clone {
951                    #[inline]
952                    fn clone(&self) -> Self {
953                        match self {
954                            Type::Primary(x) => Type::Primary(x.clone()),
955                            Type::Secondary(x) => Type::Secondary(x.clone()),
956                        }
957                    }
958
959                    #[inline]
960                    fn clone_from(&mut self, source: &Self) {
961                        match (self, source) {
962                            (Type::Primary(to), Type::Primary(from)) => to.clone_from(from),
963                            (Type::Secondary(to), Type::Secondary(from)) => to.clone_from(from),
964                            (to, from) => *to = from.clone(),
965                        }
966                    }
967                }
968
969                // impl<T: core::ops::Deref, E> Type<T, E> {
970                //     pub fn as_deref_ok(&self) -> Type<&T::Target, &E> {
971                //         self.as_ref().map(|t| t.deref())
972                //     }
973                // }
974
975                // impl<T, E: core::ops::Deref> Type<T, E> {
976                //     pub fn as_deref_err(&self) -> Type<&T, &E::Target> {
977                //         self.as_ref().map_err(|e| e.deref())
978                //     }
979                // }
980
981                impl impl_generics Type ty_generics where where_predicates T: core::ops::Deref, E: core::ops::Deref {
982                    pub fn as_deref(&self) -> Type<&T::Target, &E::Target> {
983                        self.as_ref().map(|t| t.deref()).map_err(|e| e.deref())
984                    }
985                }
986
987                // impl<T: core::ops::DerefMut, E> Type<T, E> {
988                //     pub fn as_deref_mut_ok(&mut self) -> Type<&mut T::Target, &mut E> {
989                //         self.as_mut().map(|t| t.deref_mut())
990                //     }
991                // }
992
993                // impl<T, E: core::ops::DerefMut> Type<T, E> {
994                //     pub fn as_deref_mut_err(&mut self) -> Type<&mut T, &mut E::Target> {
995                //         self.as_mut().map_err(|e| e.deref_mut())
996                //     }
997                // }
998
999                // impl<T: core::ops::DerefMut, E: core::ops::DerefMut> Type<T, E> {
1000                //     pub fn as_deref_mut(&mut self) -> Type<&mut T::Target, &mut E::Target> {
1001                //         self.as_mut()
1002                //             .map(|t| t.deref_mut())
1003                //             .map_err(|e| e.deref_mut())
1004                //     }
1005                // }
1006
1007
1008                // flatten
1009
1010                // impl<'a, T, E> IntoIterator for &'a Type<T, E> {
1011                //     type Item = &'a T;
1012                //     type IntoIter = core::result::Iter<'a, T>;
1013
1014                //     fn into_iter(self) -> core::result::Iter<'a, T> {
1015                //         self.into_result().iter()
1016                //     }
1017                // }
1018
1019                // impl<'a, T, E> IntoIterator for &'a mut Type<T, E> {
1020                //     type Item = &'a mut T;
1021                //     type IntoIter = IterMut<'a, T>;
1022
1023                //     fn into_iter(self) -> IterMut<'a, T> {
1024                //         self.iter_mut()
1025                //     }
1026                // }
1027                }
1028            ));
1029        }
1030        result_impl
1031    }
1032}