1use crate::ErrorKind;
2use regex::RegexBuilder;
3use std::{collections::BTreeSet, str::FromStr};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
7pub enum RegexFlag {
8 CaseInsensitive,
10 Global,
12 GreedySwap,
14 IgnoreWhitespaces,
16}
17
18#[derive(Debug, Default, PartialEq, Eq)]
20pub struct RegexFlags(BTreeSet<RegexFlag>);
21
22impl RegexFlags {
23 pub fn apply(&self, builder: &mut RegexBuilder) {
25 builder.case_insensitive(self.0.contains(&RegexFlag::CaseInsensitive));
26 builder.swap_greed(self.0.contains(&RegexFlag::GreedySwap));
27 builder.ignore_whitespace(self.0.contains(&RegexFlag::IgnoreWhitespaces));
28 }
29
30 pub fn is_global(&self) -> bool {
32 self.0.contains(&RegexFlag::Global)
33 }
34}
35
36impl<I: IntoIterator<Item = RegexFlag>> From<I> for RegexFlags {
37 fn from(i: I) -> Self {
38 RegexFlags(i.into_iter().collect())
39 }
40}
41
42impl FromStr for RegexFlags {
43 type Err = ErrorKind;
44
45 fn from_str(s: &str) -> Result<Self, Self::Err> {
46 s.chars()
47 .map(|c| match c {
48 'i' => Ok(RegexFlag::CaseInsensitive),
49 'g' => Ok(RegexFlag::Global),
50 'U' => Ok(RegexFlag::GreedySwap),
51 'x' => Ok(RegexFlag::IgnoreWhitespaces),
52 c => Err(ErrorKind::UnknownFlag(c)),
53 })
54 .collect::<Result<_, _>>()
55 .map(RegexFlags)
56 }
57}