logo
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use super::*;

impl<'a> AstStyle<'a> {
    ///
    #[inline]
    pub fn is_self_reference(&self) -> bool {
        matches!(self.elements.as_slice(), ["&"])
    }
}

impl<'a> AstGroup<'a> {
    ///
    #[inline]
    pub fn expand(self, styles: &mut Vec<AstStyle<'a>>) {
        let head = &self.head;
        for item in self.children {
            item.expand_with_head(styles, head)
        }
    }
}

impl<'a> Add<AstGroup<'a>> for AstStyle<'a> {
    type Output = AstGroup<'a>;
    #[inline]
    fn add(self, rhs: AstGroup<'a>) -> Self::Output {
        let mut head = self;
        head.add_assign(&rhs.head);
        AstGroup { head, children: rhs.children }
    }
}

impl<'a> AstGroupItem<'a> {
    ///
    #[inline]
    pub fn expand(self, styles: &mut Vec<AstStyle<'a>>) {
        match self {
            Self::Grouped(g) => g.expand(styles),
            Self::Styled(rhs) => styles.push(rhs),
        }
    }

    ///
    #[inline]
    pub fn expand_with_head(self, styles: &mut Vec<AstStyle<'a>>, head: &AstStyle<'a>) {
        match self {
            Self::Grouped(g) => {
                let new = head.clone().add(g);
                new.expand(styles)
            }
            Self::Styled(rhs) => {
                let mut new = head.clone();
                new.add_assign(&rhs);
                styles.push(new)
            }
        }
    }
}

impl<'a> AddAssign<&AstStyle<'a>> for AstStyle<'a> {
    #[inline]
    fn add_assign(&mut self, rhs: &AstStyle<'a>) {
        self.negative = merge_negative(self.negative, rhs.negative);
        self.variants.extend(rhs.variants.iter().cloned());
        self.arbitrary = self.arbitrary.or(self.arbitrary);
        match rhs.is_self_reference() {
            true => {}
            false => self.elements.extend(rhs.elements.iter().cloned()),
        };
    }
}

#[inline]
fn merge_negative(lhs: bool, rhs: bool) -> bool {
    match (lhs, rhs) {
        (true, true) => true,
        (true, false) | (false, true) => true,
        (false, false) => false,
    }
}