tracing_capture/predicates/
parent.rs
1use predicates::{
4 reflection::{Case, PredicateReflection, Product},
5 Predicate,
6};
7
8use std::{fmt, iter};
9
10use crate::{Captured, CapturedSpan};
11
12pub fn parent<P>(matches: P) -> ParentPredicate<P>
36where
37 P: for<'a> Predicate<CapturedSpan<'a>>,
38{
39 ParentPredicate { matches }
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47pub struct ParentPredicate<P> {
48 matches: P,
49}
50
51impl_bool_ops!(ParentPredicate<P>);
52
53impl<P> fmt::Display for ParentPredicate<P>
54where
55 P: for<'a> Predicate<CapturedSpan<'a>>,
56{
57 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
58 write!(formatter, "parent({})", self.matches)
59 }
60}
61
62impl<P> PredicateReflection for ParentPredicate<P> where P: for<'a> Predicate<CapturedSpan<'a>> {}
63
64impl<'a, P, T> Predicate<T> for ParentPredicate<P>
65where
66 T: Captured<'a>,
67 P: for<'p> Predicate<CapturedSpan<'p>>,
68{
69 fn eval(&self, variable: &T) -> bool {
70 let parent = variable.parent();
71 parent.map_or(false, |parent| self.matches.eval(&parent))
72 }
73
74 fn find_case(&self, expected: bool, variable: &T) -> Option<Case<'_>> {
75 let parent = variable.parent();
76 let parent = if let Some(parent) = parent {
77 parent
78 } else {
79 return if expected {
80 None } else {
82 let product = Product::new("parent", "None");
83 Some(Case::new(Some(self), expected).add_product(product))
84 };
85 };
86
87 let child = self.matches.find_case(expected, &parent)?;
88 Some(Case::new(Some(self), expected).add_child(child))
89 }
90}
91
92pub fn ancestor<P>(matches: P) -> AncestorPredicate<P>
118where
119 P: for<'a> Predicate<CapturedSpan<'a>>,
120{
121 AncestorPredicate { matches }
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq)]
129pub struct AncestorPredicate<P> {
130 matches: P,
131}
132
133impl_bool_ops!(AncestorPredicate<P>);
134
135impl<P> fmt::Display for AncestorPredicate<P>
136where
137 P: for<'a> Predicate<CapturedSpan<'a>>,
138{
139 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
140 write!(formatter, "ancestor({})", self.matches)
141 }
142}
143
144impl<P> PredicateReflection for AncestorPredicate<P> where P: for<'a> Predicate<CapturedSpan<'a>> {}
145
146impl<'a, P, T> Predicate<T> for AncestorPredicate<P>
147where
148 T: Captured<'a>,
149 P: for<'p> Predicate<CapturedSpan<'p>>,
150{
151 fn eval(&self, variable: &T) -> bool {
152 let mut ancestors = iter::successors(variable.parent(), CapturedSpan::parent);
153 ancestors.any(|span| self.matches.eval(&span))
154 }
155
156 fn find_case(&self, expected: bool, variable: &T) -> Option<Case<'_>> {
157 let mut ancestors = iter::successors(variable.parent(), CapturedSpan::parent);
158 if expected {
159 let child = ancestors.find_map(|span| self.matches.find_case(expected, &span))?;
161 Some(Case::new(Some(self), expected).add_child(child))
162 } else {
163 let case = Case::new(Some(self), expected);
165 ancestors.try_fold(case, |case, span| {
166 let child = self.matches.find_case(expected, &span)?;
167 Some(case.add_child(child))
168 })
169 }
170 }
171}