tor_netdoc/parse2/
structural.rs1use super::*;
4
5#[derive(Debug, Copy, Clone, derive_more::Deref)]
9#[allow(clippy::exhaustive_structs)]
10pub struct StopAt<P: StopPredicate>(pub P);
11
12pub trait StopPredicate: Copy {
16 fn stop_at(&self, kw: KeywordRef<'_>) -> bool;
22}
23impl<F: Copy + Fn(KeywordRef<'_>) -> bool> StopPredicate for F {
24 fn stop_at(&self, kw: KeywordRef<'_>) -> bool {
25 self(kw)
26 }
27}
28impl StopPredicate for bool {
29 fn stop_at(&self, _kw: KeywordRef<'_>) -> bool {
30 *self
31 }
32}
33
34#[macro_export]
39macro_rules! stop_at { {} => {
40 $crate::parse2::internal_prelude::StopAt<
41 impl $crate::parse2::internal_prelude::StopPredicate
42 >
43} }
44
45impl StopAt<bool> {
46 pub fn doc_intro<D: NetdocParseable>() -> stop_at!() {
48 StopAt(D::is_intro_item_keyword)
49 }
50}
51
52#[derive(Debug, Copy, Clone)]
54pub struct BitOrOutput<A, B>(A, B);
55
56impl<A: StopPredicate, B: StopPredicate> std::ops::BitOr<StopAt<B>> for StopAt<A> {
57 type Output = StopAt<BitOrOutput<A, B>>;
58 fn bitor(self, rhs: StopAt<B>) -> Self::Output {
59 StopAt(BitOrOutput(self.0, rhs.0))
60 }
61}
62
63impl<A: StopPredicate, B: StopPredicate> StopPredicate for BitOrOutput<A, B> {
64 fn stop_at(&self, kw: KeywordRef<'_>) -> bool {
65 self.0.stop_at(kw) || self.1.stop_at(kw)
66 }
67}