tracing_capture/predicates/
target.rs1use std::fmt;
4
5use predicates::{
6 reflection::{Case, PredicateReflection, Product},
7 Predicate,
8};
9
10use crate::Captured;
11
12pub trait IntoTargetPredicate {
14 type Predicate: Predicate<str>;
17 fn into_predicate(self) -> Self::Predicate;
19}
20
21impl<P: Predicate<str>> IntoTargetPredicate for [P; 1] {
22 type Predicate = P;
23
24 fn into_predicate(self) -> Self::Predicate {
25 self.into_iter().next().unwrap()
26 }
27}
28
29impl<'a> IntoTargetPredicate for &'a str {
30 type Predicate = TargetStrPredicate<'a>;
31
32 fn into_predicate(self) -> Self::Predicate {
33 TargetStrPredicate { prefix: self }
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub struct TargetStrPredicate<'a> {
39 prefix: &'a str,
40}
41
42impl fmt::Display for TargetStrPredicate<'_> {
43 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
44 write!(formatter, "target ^= {}", self.prefix)
45 }
46}
47
48impl PredicateReflection for TargetStrPredicate<'_> {}
49
50impl Predicate<str> for TargetStrPredicate<'_> {
51 fn eval(&self, variable: &str) -> bool {
52 variable
53 .strip_prefix(self.prefix)
54 .is_some_and(|stripped| stripped.is_empty() || stripped.starts_with("::"))
55 }
56
57 fn find_case(&self, expected: bool, variable: &str) -> Option<Case<'_>> {
58 if self.eval(variable) == expected {
59 let product = Product::new("target", variable.to_owned());
60 Some(Case::new(Some(self), expected).add_product(product))
61 } else {
62 None
63 }
64 }
65}
66
67pub fn target<P: IntoTargetPredicate>(matches: P) -> TargetPredicate<P::Predicate> {
102 TargetPredicate {
103 matches: matches.into_predicate(),
104 }
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub struct TargetPredicate<P> {
114 matches: P,
115}
116
117impl_bool_ops!(TargetPredicate<P>);
118
119impl<P: Predicate<str>> fmt::Display for TargetPredicate<P> {
120 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
121 write!(formatter, "target({})", self.matches)
122 }
123}
124
125impl<P: Predicate<str>> PredicateReflection for TargetPredicate<P> {}
126
127impl<'a, P: Predicate<str>, T: Captured<'a>> Predicate<T> for TargetPredicate<P> {
128 fn eval(&self, variable: &T) -> bool {
129 self.matches.eval(variable.metadata().target())
130 }
131
132 fn find_case(&self, expected: bool, variable: &T) -> Option<Case<'_>> {
133 let child = self
134 .matches
135 .find_case(expected, variable.metadata().target())?;
136 Some(Case::new(Some(self), expected).add_child(child))
137 }
138}