predicates/
name.rs

1// Copyright (c) 2018 The predicates-rs Project Developers.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Name predicate expressions.
10
11use std::fmt;
12use std::marker::PhantomData;
13
14use crate::reflection;
15use crate::Predicate;
16
17/// Augment an existing predicate with a name.
18///
19/// This is created by the `PredicateNameExt::name` function.
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct NamePredicate<M, Item>
22where
23    M: Predicate<Item>,
24    Item: ?Sized,
25{
26    inner: M,
27    name: &'static str,
28    _phantom: PhantomData<Item>,
29}
30
31impl<M, Item> Predicate<Item> for NamePredicate<M, Item>
32where
33    M: Predicate<Item>,
34    Item: ?Sized,
35{
36    fn eval(&self, item: &Item) -> bool {
37        self.inner.eval(item)
38    }
39
40    fn find_case<'a>(&'a self, expected: bool, variable: &Item) -> Option<reflection::Case<'a>> {
41        self.inner
42            .find_case(expected, variable)
43            .map(|child_case| reflection::Case::new(Some(self), expected).add_child(child_case))
44    }
45}
46
47impl<M, Item> reflection::PredicateReflection for NamePredicate<M, Item>
48where
49    M: Predicate<Item>,
50    Item: ?Sized,
51{
52    fn children<'a>(&'a self) -> Box<dyn Iterator<Item = reflection::Child<'a>> + 'a> {
53        let params = vec![reflection::Child::new(self.name, &self.inner)];
54        Box::new(params.into_iter())
55    }
56}
57
58impl<M, Item> fmt::Display for NamePredicate<M, Item>
59where
60    M: Predicate<Item>,
61    Item: ?Sized,
62{
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        write!(f, "{}", self.name)
65    }
66}
67
68/// `Predicate` extension that adds naming predicate expressions.
69pub trait PredicateNameExt<Item: ?Sized>
70where
71    Self: Predicate<Item>,
72{
73    /// Name a predicate expression.
74    ///
75    /// # Examples
76    ///
77    /// ```
78    /// use predicates::prelude::*;
79    ///
80    /// let predicate_fn = predicate::str::is_empty().not().name("non-empty");
81    /// println!("{}", predicate_fn);
82    /// ```
83    fn name(self, name: &'static str) -> NamePredicate<Self, Item>
84    where
85        Self: Sized,
86    {
87        NamePredicate {
88            inner: self,
89            name,
90            _phantom: PhantomData,
91        }
92    }
93}
94
95impl<P, Item> PredicateNameExt<Item> for P
96where
97    P: Predicate<Item>,
98    Item: ?Sized,
99{
100}