summaryrefslogtreecommitdiff
path: root/tests/src/spanless.rs
blob: 87d3f39d68dd2baed3831216d1587356a95d0b5b (plain) (blame)
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
use super::*;


/// Compares elements by only looking at values and ignoring spans.
pub trait SpanlessEq<T> {
    fn spanless_eq(&self, other: &T) -> bool;
}

impl SpanlessEq<Vec<Spanned<Token<'_>>>> for Vec<Spanned<Token<'_>>> {
    fn spanless_eq(&self, other: &Vec<Spanned<Token>>) -> bool {
        self.len() == other.len()
        && self.iter().zip(other).all(|(x, y)| x.v == y.v)
    }
}

impl SpanlessEq<SyntaxModel> for SyntaxModel {
    fn spanless_eq(&self, other: &SyntaxModel) -> bool {
        fn downcast(func: &dyn Model) -> &DebugFn {
            func.downcast::<DebugFn>().expect("not a debug fn")
        }

        self.nodes.len() == other.nodes.len()
        && self.nodes.iter().zip(&other.nodes).all(|(x, y)| match (&x.v, &y.v) {
            (Node::Model(a), Node::Model(b)) => {
                downcast(a.as_ref()).spanless_eq(downcast(b.as_ref()))
            }
            (a, b) => a == b,
        })
    }
}

impl SpanlessEq<DebugFn> for DebugFn {
    fn spanless_eq(&self, other: &DebugFn) -> bool {
        self.header.name.v == other.header.name.v
        && self.header.args.positional.spanless_eq(&other.header.args.positional)
        && self.header.args.keyword.spanless_eq(&other.header.args.keyword)
    }
}

impl SpanlessEq<Expression> for Expression {
    fn spanless_eq(&self, other: &Expression) -> bool {
        match (self, other) {
            (Expression::Tuple(a), Expression::Tuple(b)) => a.spanless_eq(b),
            (Expression::Object(a), Expression::Object(b)) => a.spanless_eq(b),
            (a, b) => a == b,
        }
    }
}

impl SpanlessEq<Tuple> for Tuple {
    fn spanless_eq(&self, other: &Tuple) -> bool {
        self.items.len() == other.items.len()
        && self.items.iter().zip(&other.items)
            .all(|(x, y)| x.v.spanless_eq(&y.v))
    }
}

impl SpanlessEq<Object> for Object {
    fn spanless_eq(&self, other: &Object) -> bool {
        self.pairs.len() == other.pairs.len()
        && self.pairs.iter().zip(&other.pairs)
            .all(|(x, y)| x.key.v == y.key.v && x.value.v.spanless_eq(&y.value.v))
    }
}