tracing_capture/predicates/
parent.rs1use std::{fmt, iter};
4
5use predicates::{
6 reflection::{Case, PredicateReflection, Product},
7 Predicate,
8};
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.is_some_and(|parent| self.matches.eval(&parent))
72 }
73
74 fn find_case(&self, expected: bool, variable: &T) -> Option<Case<'_>> {
75 let Some(parent) = variable.parent() else {
76 return if expected {
77 None } else {
79 let product = Product::new("parent", "None");
80 Some(Case::new(Some(self), expected).add_product(product))
81 };
82 };
83
84 let child = self.matches.find_case(expected, &parent)?;
85 Some(Case::new(Some(self), expected).add_child(child))
86 }
87}
88
89pub fn ancestor<P>(matches: P) -> AncestorPredicate<P>
115where
116 P: for<'a> Predicate<CapturedSpan<'a>>,
117{
118 AncestorPredicate { matches }
119}
120
121#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126pub struct AncestorPredicate<P> {
127 matches: P,
128}
129
130impl_bool_ops!(AncestorPredicate<P>);
131
132impl<P> fmt::Display for AncestorPredicate<P>
133where
134 P: for<'a> Predicate<CapturedSpan<'a>>,
135{
136 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
137 write!(formatter, "ancestor({})", self.matches)
138 }
139}
140
141impl<P> PredicateReflection for AncestorPredicate<P> where P: for<'a> Predicate<CapturedSpan<'a>> {}
142
143impl<'a, P, T> Predicate<T> for AncestorPredicate<P>
144where
145 T: Captured<'a>,
146 P: for<'p> Predicate<CapturedSpan<'p>>,
147{
148 fn eval(&self, variable: &T) -> bool {
149 let mut ancestors = iter::successors(variable.parent(), CapturedSpan::parent);
150 ancestors.any(|span| self.matches.eval(&span))
151 }
152
153 fn find_case(&self, expected: bool, variable: &T) -> Option<Case<'_>> {
154 let mut ancestors = iter::successors(variable.parent(), CapturedSpan::parent);
155 if expected {
156 let child = ancestors.find_map(|span| self.matches.find_case(expected, &span))?;
158 Some(Case::new(Some(self), expected).add_child(child))
159 } else {
160 let case = Case::new(Some(self), expected);
162 ancestors.try_fold(case, |case, span| {
163 let child = self.matches.find_case(expected, &span)?;
164 Some(case.add_child(child))
165 })
166 }
167 }
168}