Skip to main content

ct_regex_internal/matcher/
class.rs

1use std::cmp::Ordering;
2use std::fmt::{self, Debug};
3use std::marker::PhantomData;
4
5use crate::expr::IndexedCaptures;
6use crate::haystack::{HaystackItem, HaystackOf};
7use crate::matcher::{Matcher, impl_all_captures_single, impl_all_matches_single};
8use crate::sealed::Sealed;
9
10#[derive(#[automatically_derived]
impl<I: ::core::clone::Clone + HaystackItem> ::core::clone::Clone for
    ClassEntry<I> {
    #[inline]
    fn clone(&self) -> ClassEntry<I> {
        ClassEntry {
            value: ::core::clone::Clone::clone(&self.value),
            is_upper_bound: ::core::clone::Clone::clone(&self.is_upper_bound),
        }
    }
}Clone, #[automatically_derived]
impl<I: ::core::cmp::PartialEq + HaystackItem> ::core::cmp::PartialEq for
    ClassEntry<I> {
    #[inline]
    fn eq(&self, other: &ClassEntry<I>) -> bool {
        self.is_upper_bound == other.is_upper_bound &&
            self.value == other.value
    }
}PartialEq, #[automatically_derived]
impl<I: ::core::cmp::Eq + HaystackItem> ::core::cmp::Eq for ClassEntry<I> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<I>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq)]
11pub struct ClassEntry<I: HaystackItem> {
12    pub value: I,
13    pub is_upper_bound: bool,
14}
15
16impl<I: HaystackItem> ClassEntry<I> {
17    pub const fn new(value: I, is_upper_bound: bool) -> ClassEntry<I> {
18        ClassEntry { value, is_upper_bound }
19    }
20
21    pub fn cmp_item(&self, item: &I) -> Ordering {
22        self.value.cmp(item)
23    }
24}
25
26impl<I: HaystackItem> PartialEq<I> for ClassEntry<I> {
27    fn eq(&self, other: &I) -> bool {
28        &self.value == other
29    }
30}
31
32impl<I: HaystackItem> PartialOrd for ClassEntry<I> {
33    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
34        Some(self.cmp(other))
35    }
36}
37
38impl<I: HaystackItem> Ord for ClassEntry<I> {
39    fn cmp(&self, other: &Self) -> Ordering {
40        self.value.cmp(&other.value)
41    }
42}
43
44impl<I: HaystackItem> Debug for ClassEntry<I> {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        if self.is_upper_bound {
47            f.write_fmt(format_args!("-"))write!(f, "-")?;
48        }
49        f.write_fmt(format_args!("{0:?}", self.value))write!(f, "{:?}", self.value)
50    }
51}
52
53pub trait Class<I: HaystackItem>: Default + Clone + Copy {
54    const ENTRIES: &[ClassEntry<I>];
55}
56
57#[derive(#[automatically_derived]
impl<I: ::core::default::Default + HaystackItem, C: ::core::default::Default +
    Class<I>> ::core::default::Default for ClassMatcher<I, C> {
    #[inline]
    fn default() -> ClassMatcher<I, C> {
        ClassMatcher(::core::default::Default::default())
    }
}Default, #[automatically_derived]
impl<I: ::core::clone::Clone + HaystackItem, C: ::core::clone::Clone +
    Class<I>> ::core::clone::Clone for ClassMatcher<I, C> {
    #[inline]
    fn clone(&self) -> ClassMatcher<I, C> {
        ClassMatcher(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]
impl<I: ::core::marker::Copy + HaystackItem, C: ::core::marker::Copy +
    Class<I>> ::core::marker::Copy for ClassMatcher<I, C> {
}Copy)]
58pub struct ClassMatcher<I: HaystackItem, C: Class<I>>(pub PhantomData<(I, C)>);
59
60impl<I: HaystackItem, C: Class<I>> Sealed for ClassMatcher<I, C> {}
61
62impl<I: HaystackItem, C: Class<I>> Matcher<I> for ClassMatcher<I, C> {
63    fn matches<'a, H: HaystackOf<'a, I>>(hay: &mut H) -> bool {
64        let Some(item) = hay.next() else {
65            return false;
66        };
67        match C::ENTRIES.binary_search_by(|entry| entry.cmp_item(&item)) {
68            Ok(_) => true,
69            // We've failed the exact binary search, but if the target index for insertion is an
70            // upper bound, we're in the middle of a range. Still counts as a match.
71            Err(index) if C::ENTRIES.get(index).is_some_and(|entry| entry.is_upper_bound) => true,
72            _ => false,
73        }
74    }
75
76    I
crate::matcher::AllMatchesSingle
I
&mut H
hay
Self::AllMatches<'a, H>
crate::matcher::all_matches_single::<I, H, Self>(hay);impl_all_matches_single!(I);
77    I
crate::matcher::AllCapturesSingle
I
&mut H
hay
&mut IndexedCaptures
caps
Self::AllCaptures<'a, H>
crate::matcher::all_captures_single::<I, H, Self>(hay, caps);impl_all_captures_single!(I);
78}
79
80impl<I: HaystackItem, C: Class<I>> Debug for ClassMatcher<I, C> {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        f.write_fmt(format_args!("["))write!(f, "[")?;
83        for entry in C::ENTRIES {
84            f.write_fmt(format_args!("{0:?}", entry))write!(f, "{:?}", entry)?;
85        }
86        f.write_fmt(format_args!("]"))write!(f, "]")
87    }
88}