litcheck_filecheck/pattern/
prefix.rs1use crate::{
2 ast::{Match, RegexPattern},
3 common::*,
4};
5
6#[derive(Debug)]
7pub enum PatternPrefix<'a> {
8 Literal {
10 id: usize,
11 prefix: Span<Cow<'a, str>>,
12 },
13 Substring {
15 id: usize,
16 prefix: Span<Cow<'a, str>>,
17 },
18 Regex { id: usize, prefix: RegexPattern<'a> },
20 Dynamic {
23 id: usize,
24 prefix: Cow<'a, Match<'a>>,
25 },
26}
27impl<'a> PatternPrefix<'a> {
28 pub fn id(&self) -> usize {
29 match self {
30 Self::Literal { id, .. }
31 | Self::Substring { id, .. }
32 | Self::Regex { id, .. }
33 | Self::Dynamic { id, .. } => *id,
34 }
35 }
36
37 pub fn span(&self) -> SourceSpan {
38 match self {
39 Self::Literal { prefix, .. } | Self::Substring { prefix, .. } => prefix.span(),
40 Self::Regex { prefix, .. } => prefix.span(),
41 Self::Dynamic { prefix, .. } => prefix.span(),
42 }
43 }
44
45 pub fn as_str(&self) -> Option<&str> {
46 match self {
47 Self::Literal { prefix, .. } | Self::Substring { prefix, .. } => Some(prefix.as_ref()),
48 Self::Regex { prefix, .. } => Some(prefix.as_ref()),
49 Self::Dynamic { .. } => None,
50 }
51 }
52
53 pub fn to_str(&self) -> Option<Span<Cow<'a, str>>> {
54 match self {
55 Self::Literal { prefix, .. } | Self::Substring { prefix, .. } => Some(prefix.clone()),
56 Self::Regex { prefix, .. } => Some(prefix.pattern.clone()),
57 Self::Dynamic { .. } => None,
58 }
59 }
60
61 pub fn into_str(self) -> Option<Span<Cow<'a, str>>> {
62 match self {
63 Self::Literal { prefix, .. } | Self::Substring { prefix, .. } => Some(prefix),
64 Self::Regex { prefix, .. } => Some(prefix.pattern),
65 Self::Dynamic { .. } => None,
66 }
67 }
68
69 pub fn into_regex_pattern(self) -> Option<RegexPattern<'a>> {
70 match self {
71 Self::Literal { prefix, .. } | Self::Substring { prefix, .. } => Some(
72 RegexPattern::new(prefix.map(|s| Cow::Owned(regex::escape(s.as_ref())))),
73 ),
74 Self::Regex { prefix, .. } => Some(prefix),
75 Self::Dynamic { .. } => None,
76 }
77 }
78
79 pub fn is_regex(&self) -> bool {
80 matches!(self, Self::Regex { .. })
81 }
82
83 pub fn is_regex_compatible(&self) -> bool {
84 matches!(
85 self,
86 Self::Regex { .. } | Self::Literal { .. } | Self::Substring { .. }
87 )
88 }
89
90 pub fn is_dynamic(&self) -> bool {
91 matches!(self, Self::Dynamic { .. })
92 }
93
94 pub fn is_capturing(&self) -> bool {
95 match self {
96 Self::Regex { prefix, .. } if !prefix.captures.is_empty() => true,
97 Self::Dynamic { .. } => true,
98 _ => false,
99 }
100 }
101
102 pub fn overlaps(&self, prefix: &str) -> bool {
104 self.as_str()
105 .map(|p| p.starts_with(prefix))
106 .unwrap_or(false)
107 }
108
109 pub fn is_overlapped_by(&self, prefix: &str) -> bool {
111 self.as_str()
112 .map(|p| prefix.starts_with(p))
113 .unwrap_or(false)
114 }
115
116 pub fn is_duplicate_prefix(&self, prefix: &str) -> bool {
118 self.as_str().map(|p| p == prefix).unwrap_or(false)
119 }
120}