litcheck_filecheck/rules/
mod.rs

1mod dag;
2mod empty;
3mod next;
4mod plain;
5mod same;
6
7pub use self::dag::CheckDag;
8pub use self::empty::CheckEmpty;
9pub use self::next::CheckNext;
10pub use self::plain::CheckPlain;
11pub use self::same::CheckSame;
12
13use std::fmt;
14
15use crate::common::{Check, Context, DiagResult, Matches, Spanned};
16
17pub trait Rule: fmt::Debug + Spanned {
18    fn kind(&self) -> Check;
19    fn apply<'input, 'context, C>(&self, context: &mut C) -> DiagResult<Matches<'input>>
20    where
21        C: Context<'input, 'context> + ?Sized;
22}
23impl<'r, R> Rule for &'r R
24where
25    R: ?Sized + Rule,
26{
27    #[inline(always)]
28    fn kind(&self) -> Check {
29        <R as Rule>::kind(self)
30    }
31    #[inline(always)]
32    fn apply<'input, 'context, C>(&self, context: &mut C) -> DiagResult<Matches<'input>>
33    where
34        C: Context<'input, 'context> + ?Sized,
35    {
36        <R as Rule>::apply(self, context)
37    }
38}
39impl<R> Rule for Box<R>
40where
41    R: Rule + ?Sized,
42{
43    #[inline(always)]
44    fn kind(&self) -> Check {
45        (**self).kind()
46    }
47    #[inline(always)]
48    fn apply<'input, 'context, C>(&self, context: &mut C) -> DiagResult<Matches<'input>>
49    where
50        C: Context<'input, 'context> + ?Sized,
51    {
52        (**self).apply(context)
53    }
54}
55
56pub trait DynRule: fmt::Debug + Spanned {
57    fn kind(&self) -> Check;
58    fn apply_dyn<'input>(
59        &self,
60        context: &mut dyn Context<'input, '_>,
61    ) -> DiagResult<Matches<'input>>;
62}
63impl<'context> Rule for (dyn DynRule + 'context) {
64    #[inline(always)]
65    fn kind(&self) -> Check {
66        Self::kind(self)
67    }
68    #[inline(always)]
69    fn apply<'input, 'ctx, C>(&self, context: &mut C) -> DiagResult<Matches<'input>>
70    where
71        C: Context<'input, 'ctx> + ?Sized,
72    {
73        let mut passthrough = context.protect();
74        let result = self.apply_dyn(&mut passthrough)?;
75        passthrough.save();
76        Ok(result)
77    }
78}
79
80impl<R> DynRule for R
81where
82    R: Rule + ?Sized,
83{
84    #[inline(always)]
85    fn kind(&self) -> Check {
86        <R as Rule>::kind(self)
87    }
88    #[inline(always)]
89    fn apply_dyn<'input>(
90        &self,
91        context: &mut dyn Context<'input, '_>,
92    ) -> DiagResult<Matches<'input>> {
93        <R as Rule>::apply(self, context)
94    }
95}