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}