test_strategy/
bound.rs

1use proc_macro2::TokenStream;
2use std::ops::{Deref, DerefMut};
3use syn::Token;
4use syn::{
5    parse::{discouraged::Speculative, Parse, ParseStream},
6    parse_quote, Result, Type, WherePredicate,
7};
8
9#[allow(clippy::large_enum_variant)]
10pub enum Bound {
11    Type(Type),
12    Predicate(WherePredicate),
13    Default(Token![..]),
14}
15impl Parse for Bound {
16    fn parse(input: ParseStream) -> Result<Self> {
17        if input.peek(Token![..]) {
18            return Ok(Self::Default(input.parse()?));
19        }
20        let fork = input.fork();
21        match fork.parse() {
22            Ok(p) => {
23                input.advance_to(&fork);
24                Ok(Self::Predicate(p))
25            }
26            Err(e) => {
27                if let Ok(ty) = input.parse() {
28                    Ok(Self::Type(ty))
29                } else {
30                    Err(e)
31                }
32            }
33        }
34    }
35}
36
37pub struct Bounds {
38    pub ty: Vec<Type>,
39    pub pred: Vec<WherePredicate>,
40    pub can_extend: bool,
41}
42impl Bounds {
43    pub fn new(can_extend: bool) -> Self {
44        Bounds {
45            ty: Vec::new(),
46            pred: Vec::new(),
47            can_extend,
48        }
49    }
50    pub fn from_data(bound: Option<Vec<Bound>>) -> Self {
51        if let Some(bound) = bound {
52            let mut bs = Self::new(false);
53            for b in bound {
54                bs.push(b);
55            }
56            bs
57        } else {
58            Self::new(true)
59        }
60    }
61    fn push(&mut self, bound: Bound) {
62        match bound {
63            Bound::Type(ty) => self.ty.push(ty),
64            Bound::Predicate(pred) => self.pred.push(pred),
65            Bound::Default(_) => self.can_extend = true,
66        }
67    }
68    pub fn child(&mut self, bound: Option<Vec<Bound>>) -> BoundsChild {
69        let bounds = if self.can_extend {
70            Self::from_data(bound)
71        } else {
72            Self::new(false)
73        };
74        BoundsChild {
75            owner: self,
76            bounds,
77        }
78    }
79    pub fn build_wheres(self, type_param_bounds: TokenStream) -> Vec<WherePredicate> {
80        let mut pred = self.pred;
81        for ty in self.ty {
82            pred.push(parse_quote!(#ty : #type_param_bounds));
83        }
84        pred
85    }
86}
87pub struct BoundsChild<'a> {
88    owner: &'a mut Bounds,
89    bounds: Bounds,
90}
91impl<'a> Deref for BoundsChild<'a> {
92    type Target = Bounds;
93
94    fn deref(&self) -> &Self::Target {
95        &self.bounds
96    }
97}
98impl<'a> DerefMut for BoundsChild<'a> {
99    fn deref_mut(&mut self) -> &mut Self::Target {
100        &mut self.bounds
101    }
102}
103impl<'a> Drop for BoundsChild<'a> {
104    fn drop(&mut self) {
105        if self.owner.can_extend {
106            self.owner.ty.append(&mut self.bounds.ty);
107            self.owner.pred.append(&mut self.bounds.pred);
108        }
109    }
110}