semver_php/constraint/
mod.rs1pub mod bound;
2pub mod match_all;
3pub mod match_none;
4pub mod multi;
5pub mod single;
6
7pub use bound::Bound;
8pub use match_all::MatchAllConstraint;
9pub use match_none::MatchNoneConstraint;
10pub use multi::MultiConstraint;
11pub use single::SingleConstraint;
12
13use crate::error::{Result, SemverError};
14use std::fmt;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub enum Operator {
19 Eq,
21 Ne,
23 Lt,
25 Le,
27 Gt,
29 Ge,
31}
32
33impl Operator {
34 pub fn parse(s: &str) -> Result<Self> {
39 match s {
40 "=" | "==" => Ok(Self::Eq),
41 "!=" | "<>" => Ok(Self::Ne),
42 "<" => Ok(Self::Lt),
43 "<=" => Ok(Self::Le),
44 ">" => Ok(Self::Gt),
45 ">=" => Ok(Self::Ge),
46 _ => Err(SemverError::InvalidOperator(s.to_string())),
47 }
48 }
49
50 #[must_use]
52 pub const fn as_str(&self) -> &'static str {
53 match self {
54 Self::Eq => "==",
55 Self::Ne => "!=",
56 Self::Lt => "<",
57 Self::Le => "<=",
58 Self::Gt => ">",
59 Self::Ge => ">=",
60 }
61 }
62
63 #[must_use]
65 pub const fn inverse(&self) -> Self {
66 match self {
67 Self::Eq => Self::Eq,
68 Self::Ne => Self::Ne,
69 Self::Lt => Self::Gt,
70 Self::Le => Self::Ge,
71 Self::Gt => Self::Lt,
72 Self::Ge => Self::Le,
73 }
74 }
75}
76
77impl fmt::Display for Operator {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 write!(f, "{}", self.as_str())
80 }
81}
82
83pub trait Constraint: fmt::Display + fmt::Debug + Send + Sync {
85 fn matches(&self, other: &dyn Constraint) -> bool;
87
88 fn lower_bound(&self) -> Bound;
90
91 fn upper_bound(&self) -> Bound;
93
94 fn pretty_string(&self) -> String {
96 self.to_string()
97 }
98
99 fn set_pretty_string(&mut self, _pretty: String) {
101 }
103
104 fn is_match_all(&self) -> bool {
106 false
107 }
108
109 fn is_match_none(&self) -> bool {
111 false
112 }
113
114 fn as_single(&self) -> Option<&SingleConstraint> {
116 None
117 }
118
119 fn as_multi(&self) -> Option<&MultiConstraint> {
121 None
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128
129 #[test]
130 fn test_operator_parse() {
131 assert_eq!(Operator::parse("=").unwrap(), Operator::Eq);
132 assert_eq!(Operator::parse("==").unwrap(), Operator::Eq);
133 assert_eq!(Operator::parse("!=").unwrap(), Operator::Ne);
134 assert_eq!(Operator::parse("<>").unwrap(), Operator::Ne);
135 assert_eq!(Operator::parse("<").unwrap(), Operator::Lt);
136 assert_eq!(Operator::parse("<=").unwrap(), Operator::Le);
137 assert_eq!(Operator::parse(">").unwrap(), Operator::Gt);
138 assert_eq!(Operator::parse(">=").unwrap(), Operator::Ge);
139 assert!(Operator::parse("??").is_err());
140 }
141
142 #[test]
143 fn test_operator_inverse() {
144 assert_eq!(Operator::Lt.inverse(), Operator::Gt);
145 assert_eq!(Operator::Gt.inverse(), Operator::Lt);
146 assert_eq!(Operator::Le.inverse(), Operator::Ge);
147 assert_eq!(Operator::Ge.inverse(), Operator::Le);
148 assert_eq!(Operator::Eq.inverse(), Operator::Eq);
149 assert_eq!(Operator::Ne.inverse(), Operator::Ne);
150 }
151}