litcheck_filecheck/ast/
modifier.rs1use std::str::FromStr;
2
3use crate::common::*;
4
5#[derive(Debug)]
6pub struct InvalidCheckModifierError;
7
8bitflags::bitflags! {
9 #[derive(Copy, Clone)]
11 pub struct CheckModifier: u16 {
12 const LITERAL = 1;
13 const COUNT = 2;
14 }
15}
16impl Default for CheckModifier {
17 fn default() -> Self {
18 Self::empty()
19 }
20}
21impl FromStr for CheckModifier {
22 type Err = InvalidCheckModifierError;
23
24 fn from_str(s: &str) -> Result<Self, Self::Err> {
25 match s {
26 "LITERAL" | "literal" => Ok(Self::LITERAL),
27 _ => Err(InvalidCheckModifierError),
28 }
29 }
30}
31impl fmt::Debug for CheckModifier {
32 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33 use std::fmt::Write;
34 f.write_str("CheckModifier(")?;
35 let mut mods = 0;
36 if self.contains(Self::LITERAL) {
37 mods += 1;
38 f.write_str("LITERAL")?;
39 }
40 if self.contains(Self::COUNT) {
41 if mods > 0 {
42 f.write_str(" | ")?;
43 }
44 write!(f, "COUNT({})", self.count())?;
45 }
46 f.write_char(')')
47 }
48}
49impl CheckModifier {
50 pub fn is_literal(&self) -> bool {
51 self.contains(Self::LITERAL)
52 }
53
54 pub fn from_count(count: u8) -> Self {
55 let count = (count as u16) << 2;
56 Self::COUNT | CheckModifier::from_bits_retain(count)
57 }
58
59 pub fn count(&self) -> usize {
60 if self.contains(Self::COUNT) {
61 (self.bits() >> 2) as usize
62 } else {
63 1
64 }
65 }
66}
67impl Eq for CheckModifier {}
68impl PartialEq for CheckModifier {
69 fn eq(&self, other: &Self) -> bool {
70 self.count() == other.count() && self.is_literal() == other.is_literal()
71 }
72}