pumpkin_checking/
atomic_constraint.rs1use std::fmt::Debug;
2use std::fmt::Display;
3use std::hash::Hash;
4
5pub trait AtomicConstraint: Clone + Debug + Sized {
12 type Identifier: Hash + Eq;
14
15 fn identifier(&self) -> Self::Identifier;
17
18 fn comparison(&self) -> Comparison;
20
21 fn value(&self) -> i32;
23
24 fn negate(&self) -> Self;
26}
27
28#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
30pub enum Comparison {
31 GreaterEqual,
32 LessEqual,
33 Equal,
34 NotEqual,
35}
36
37impl Display for Comparison {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 let s = match self {
40 Comparison::GreaterEqual => ">=",
41 Comparison::LessEqual => "<=",
42 Comparison::Equal => "==",
43 Comparison::NotEqual => "!=",
44 };
45
46 write!(f, "{s}")
47 }
48}
49
50#[derive(Clone, Copy, Debug, PartialEq)]
52pub struct TestAtomic {
53 pub name: &'static str,
54 pub comparison: Comparison,
55 pub value: i32,
56}
57
58impl AtomicConstraint for TestAtomic {
59 type Identifier = &'static str;
60
61 fn identifier(&self) -> Self::Identifier {
62 self.name
63 }
64
65 fn comparison(&self) -> Comparison {
66 self.comparison
67 }
68
69 fn value(&self) -> i32 {
70 self.value
71 }
72
73 fn negate(&self) -> Self {
74 TestAtomic {
75 name: self.name,
76 comparison: match self.comparison {
77 Comparison::GreaterEqual => Comparison::LessEqual,
78 Comparison::LessEqual => Comparison::GreaterEqual,
79 Comparison::Equal => Comparison::NotEqual,
80 Comparison::NotEqual => Comparison::Equal,
81 },
82 value: match self.comparison {
83 Comparison::GreaterEqual => self.value - 1,
84 Comparison::LessEqual => self.value + 1,
85 Comparison::NotEqual | Comparison::Equal => self.value,
86 },
87 }
88 }
89}
90
91#[macro_export]
99macro_rules! test_atomic {
100 (@to_comparison >=) => {
101 $crate::Comparison::GreaterEqual
102 };
103 (@to_comparison <=) => {
104 $crate::Comparison::LessEqual
105 };
106 (@to_comparison ==) => {
107 $crate::Comparison::Equal
108 };
109 (@to_comparison !=) => {
110 $crate::Comparison::NotEqual
111 };
112
113 ([$name:ident $comp:tt $value:expr]) => {
114 $crate::TestAtomic {
115 name: stringify!($name),
116 comparison: $crate::test_atomic!(@to_comparison $comp),
117 value: $value,
118 }
119 };
120}