semver_php/constraint/
match_none.rs

1use super::{Bound, Constraint};
2use std::fmt;
3
4/// A constraint that matches no versions (empty/impossible constraint).
5#[derive(Debug, Clone, Default)]
6pub struct MatchNoneConstraint {
7	pretty_string: Option<String>,
8}
9
10impl MatchNoneConstraint {
11	/// Create a new match-none constraint.
12	#[must_use]
13	pub fn new() -> Self {
14		Self::default()
15	}
16}
17
18impl Constraint for MatchNoneConstraint {
19	fn matches(&self, _other: &dyn Constraint) -> bool {
20		// Match-none always returns false
21		false
22	}
23
24	fn lower_bound(&self) -> Bound {
25		// Empty range: exclusive zero
26		Bound::new("0.0.0.0-dev", false)
27	}
28
29	fn upper_bound(&self) -> Bound {
30		// Empty range: exclusive zero
31		Bound::new("0.0.0.0-dev", false)
32	}
33
34	fn is_match_none(&self) -> bool {
35		true
36	}
37
38	fn set_pretty_string(&mut self, pretty: String) {
39		self.pretty_string = Some(pretty);
40	}
41
42	fn pretty_string(&self) -> String {
43		self.pretty_string
44			.clone()
45			.unwrap_or_else(|| self.to_string())
46	}
47}
48
49impl fmt::Display for MatchNoneConstraint {
50	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51		write!(f, "[]")
52	}
53}
54
55#[cfg(test)]
56mod tests {
57	use super::*;
58	use crate::constraint::{Operator, SingleConstraint};
59
60	#[test]
61	fn test_match_none_matches_nothing() {
62		let match_none = MatchNoneConstraint::new();
63
64		let eq = SingleConstraint::new(Operator::Eq, "1.0.0");
65		assert!(!match_none.matches(&eq));
66
67		let lt = SingleConstraint::new(Operator::Lt, "2.0.0");
68		assert!(!match_none.matches(&lt));
69	}
70
71	#[test]
72	fn test_is_match_none() {
73		let match_none = MatchNoneConstraint::new();
74		assert!(match_none.is_match_none());
75		assert!(!match_none.is_match_all());
76	}
77}