sophia_api/term/matcher/
_trait.rs

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use super::*;

/// Generic trait for matching [`Term`]s.
pub trait TermMatcher {
    /// The type of term that this TermMatcher contains
    type Term: Term + ?Sized;

    /// Check whether this matcher matches `t`.
    fn matches<T2: Term + ?Sized>(&self, term: &T2) -> bool;

    /// Return `None`, unless this matcher can only match a single term,
    /// in which case this method may return that term.
    ///
    /// This method is provided for optimization purposes,
    /// so implementing it is optional.
    fn constant(&self) -> Option<&Self::Term> {
        None
    }

    /// Converts this [`TermMatcher`] into a [`GraphNameMatcher`]
    ///
    /// If you only want to borrow this matcher as a [`GraphNameMatcher`],
    /// call [`gn`](TermMatcher::gn) on the result of [`matcher_ref`](TermMatcher::matcher_ref).
    fn gn(self) -> TermMatcherGn<Self>
    where
        Self: Sized,
    {
        TermMatcherGn(self)
    }

    /// Return a [`TermMatcher`] that is actually just a reference to this one.
    fn matcher_ref(&self) -> MatcherRef<'_, Self> {
        MatcherRef(self)
    }
}

/// Matches the wrapped term if any, otherwise matches nothing.
impl<T> TermMatcher for Option<T>
where
    T: Term,
{
    type Term = T;

    fn matches<T2: Term + ?Sized>(&self, term: &T2) -> bool {
        match self {
            Some(mine) => mine.eq(term.borrow_term()),
            None => false,
        }
    }
    fn constant(&self) -> Option<&Self::Term> {
        self.as_ref()
    }
}

/// Matches any of the terms in the array.
impl<T, const N: usize> TermMatcher for [T; N]
where
    T: Term,
{
    type Term = T;

    fn matches<T2: Term + ?Sized>(&self, term: &T2) -> bool {
        self.iter().any(|mine| mine.eq(term.borrow_term()))
    }
    fn constant(&self) -> Option<&Self::Term> {
        if N == 1 {
            Some(&self[0])
        } else {
            None
        }
    }
}

/// Matches any of the terms in the slice.
impl<T> TermMatcher for &[T]
where
    T: Term,
{
    type Term = T;

    fn matches<T2: Term + ?Sized>(&self, term: &T2) -> bool {
        self.iter().any(|mine| mine.eq(term.borrow_term()))
    }
    fn constant(&self) -> Option<&Self::Term> {
        if self.len() == 1 {
            Some(&self[0])
        } else {
            None
        }
    }
}

/// Matches only embedded triple whose components match the corresponding matchers.
impl<S, P, O> TermMatcher for (S, P, O)
where
    S: TermMatcher,
    P: TermMatcher,
    O: TermMatcher,
{
    type Term = S::Term; // not actually used

    fn matches<T2: Term + ?Sized>(&self, term: &T2) -> bool {
        let (sm, pm, om) = self;
        match term.triple() {
            None => false,
            Some(t) => t.matched_by(sm.matcher_ref(), pm.matcher_ref(), om.matcher_ref()),
        }
    }
}

/// Matches any term if the given kind
impl TermMatcher for TermKind {
    type Term = SimpleTerm<'static>; // not actually used

    fn matches<T2: Term + ?Sized>(&self, term: &T2) -> bool {
        term.kind() == *self
    }
}

/// Matches any term satisfying the function.
impl<F> TermMatcher for F
where
    F: Fn(SimpleTerm<'_>) -> bool + ?Sized,
{
    type Term = SimpleTerm<'static>; // not actually used

    fn matches<T2: Term + ?Sized>(&self, term: &T2) -> bool {
        (self)(term.as_simple())
    }
}