diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/mozart-constraint/src/lib.rs | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/crates/mozart-constraint/src/lib.rs b/crates/mozart-constraint/src/lib.rs index e41818c..7c417ec 100644 --- a/crates/mozart-constraint/src/lib.rs +++ b/crates/mozart-constraint/src/lib.rs @@ -365,23 +365,28 @@ impl VersionConstraint { } } -/// Split on `||` (pipe-OR), but not inside version strings. +/// Split on `|` or `||` (pipe-OR). Composer accepts both forms. fn split_or(s: &str) -> Vec<&str> { let mut parts = Vec::new(); let mut start = 0; let bytes = s.as_bytes(); let mut i = 0; while i < bytes.len() { - if i + 1 < bytes.len() && bytes[i] == b'|' && bytes[i + 1] == b'|' { + if bytes[i] == b'|' { parts.push(s[start..i].trim()); - i += 2; + i += 1; + // Skip second pipe if `||` + if i < bytes.len() && bytes[i] == b'|' { + i += 1; + } start = i; } else { i += 1; } } parts.push(s[start..].trim()); - parts + // Filter out empty parts (e.g. from leading/trailing pipes) + parts.into_iter().filter(|p| !p.is_empty()).collect() } /// Parse an AND group (space or comma separated constraints). @@ -1605,6 +1610,16 @@ mod tests { } #[test] + fn test_single_pipe_or() { + // Single pipe `|` is the standard Composer OR separator + assert!(satisfies("^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", "6.0.0")); + assert!(satisfies("^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", "9.0.0")); + assert!(satisfies("^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", "11.5.0")); + assert!(!satisfies("^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", "5.9.9")); + assert!(!satisfies("^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", "12.0.0")); + } + + #[test] fn test_combined_real_world_symfony_pattern() { // ">=5.4 <7.0" — typical Symfony range assert!(satisfies(">=5.4 <7.0", "5.4.0")); |
