Skip to content

Commit fda414f

Browse files
committed
feat(php-version): introduce PHPVersionRange for version comparisons
This commit introduces a new `PHPVersionRange` struct to the `mago-php-version` crate, providing a robust way to define and check against ranges of PHP versions. This new structure is essential for tools that need to validate version constraints, such as checking if a linter rule is applicable to a specific PHP version series. Key additions include: - The `PHPVersionRange` struct with `min` and `max` bounds. - An `includes()` method to check if a given `PHPVersion` falls within the range. - Convenience constructors like `between()`, `from()`, and `until()`. - Pre-defined constants for common ranges, such as `PHPVersionRange::PHP7` and `PHPVersionRange::PHP8`. Signed-off-by: azjezz <[email protected]>
1 parent acd0dd6 commit fda414f

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

crates/php-version/src/lib.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,27 @@ pub mod feature;
3030
#[repr(transparent)]
3131
pub struct PHPVersion(u32);
3232

33+
/// Represents a range of PHP versions, defined by a minimum and maximum version.
34+
///
35+
/// This is useful for specifying compatibility ranges, such as "supports PHP 7.0 to 7.4".
36+
///
37+
/// # Examples
38+
///
39+
/// ```
40+
/// use mago_php_version::PHPVersion;
41+
/// use mago_php_version::PHPVersionRange;
42+
///
43+
/// let range = PHPVersionRange::between(PHPVersion::new(7, 0, 0), PHPVersion::new(7, 4, 99));
44+
///
45+
/// assert!(range.includes(PHPVersion::new(7, 2, 0))); // true
46+
/// assert!(!range.includes(PHPVersion::new(8, 0, 0))); // false
47+
/// ```
48+
#[derive(Debug, PartialEq, Eq, Ord, Copy, Clone, PartialOrd, Deserialize, Serialize, Default)]
49+
pub struct PHPVersionRange {
50+
pub min: Option<PHPVersion>,
51+
pub max: Option<PHPVersion>,
52+
}
53+
3354
impl PHPVersion {
3455
/// The PHP 7.0 version.
3556
pub const PHP70: PHPVersion = PHPVersion::new(7, 0, 0);
@@ -342,6 +363,58 @@ impl PHPVersion {
342363
}
343364
}
344365

366+
impl PHPVersionRange {
367+
/// Represents the range of PHP versions from 7.0.0 to 7.99.99.
368+
pub const PHP7: PHPVersionRange = Self::between(PHPVersion::new(7, 0, 0), PHPVersion::new(7, 99, 99));
369+
370+
/// Represents the range of PHP versions from 8.0.0 to 8.99.99.
371+
pub const PHP8: PHPVersionRange = Self::between(PHPVersion::new(8, 0, 0), PHPVersion::new(8, 99, 99));
372+
373+
/// Creates a new `PHPVersionRange` that includes all versions.
374+
pub const fn any() -> Self {
375+
Self { min: None, max: None }
376+
}
377+
378+
/// Creates a new `PHPVersionRange` that includes all versions up to (and including) the specified version.
379+
pub const fn until(version: PHPVersion) -> Self {
380+
Self { min: None, max: Some(version) }
381+
}
382+
383+
/// Creates a new `PHPVersionRange` that includes all versions from (and including) the specified version.
384+
pub const fn from(version: PHPVersion) -> Self {
385+
Self { min: Some(version), max: None }
386+
}
387+
388+
/// Creates a new `PHPVersionRange` that includes all versions between (and including) the specified minimum and maximum versions.
389+
pub const fn between(min: PHPVersion, max: PHPVersion) -> Self {
390+
Self { min: Some(min), max: Some(max) }
391+
}
392+
393+
/// Checks if this version range supports the given `PHPVersion`.
394+
#[inline]
395+
pub const fn includes(&self, version: PHPVersion) -> bool {
396+
if let Some(min) = self.min
397+
&& version.0 < min.0
398+
{
399+
return false;
400+
}
401+
402+
if let Some(max) = self.max
403+
&& version.0 > max.0
404+
{
405+
return false;
406+
}
407+
408+
true
409+
}
410+
}
411+
412+
impl std::default::Default for PHPVersion {
413+
fn default() -> Self {
414+
Self::LATEST
415+
}
416+
}
417+
345418
impl std::fmt::Display for PHPVersion {
346419
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
347420
write!(f, "{}.{}.{}", self.major(), self.minor(), self.patch())

0 commit comments

Comments
 (0)