Commit a82f72e3 authored by Duncan Coutts's avatar Duncan Coutts
Browse files

Almost make the VersionRange type abstract

Export constructor functions and deprecate all the real constructors
We should not be pattern matching on this type because it's just
syntax. For meaningful questions we should be matching on the
VersionIntervals type which represents the semantics.
parent 1ffc16d8
......@@ -47,13 +47,23 @@ module Distribution.Version (
Version(..),
-- * Version ranges
VersionRange(..), notThisVersion,
VersionRange(..),
-- ** Constructing
anyVersion, noVersion,
thisVersion, notThisVersion,
laterVersion, earlierVersion,
orLaterVersion, orEarlierVersion,
unionVersionRanges, intersectVersionRanges,
betweenVersionsInclusive,
-- ** General
withinRange,
isAnyVersion,
isNoVersion,
simplify,
isSpecificVersion,
simplifyVersionRange,
foldVersionRange,
-- * Version intervals view
VersionIntervals(..),
......@@ -91,44 +101,44 @@ data VersionRange
| IntersectVersionRanges VersionRange VersionRange
deriving (Show,Read,Eq)
-- | Does this 'VersionRange' place any restriction on the 'Version' or is it
-- in fact equivalent to 'AnyVersion'.
--
-- Note this is a semantic check, not simply a syntactic check. So for example
-- the following is @True@ (for all @v@).
--
-- > isAnyVersion (EarlierVersion v `UnionVersionRanges` orLaterVersion v)
--
isAnyVersion :: VersionRange -> Bool
isAnyVersion vr = case toVersionIntervals vr of
VersionIntervals [(NoLowerBound, NoUpperBound)] -> True
_ -> False
{-# DEPRECATED AnyVersion "Use 'anyVersion', 'foldVersionRange' or 'toVersionIntervals'" #-}
{-# DEPRECATED ThisVersion "use 'thisVersion', 'foldVersionRange' or 'toVersionIntervals'" #-}
{-# DEPRECATED LaterVersion "use 'laterVersion', 'foldVersionRange' or 'toVersionIntervals'" #-}
{-# DEPRECATED EarlierVersion "use 'earlierVersion', 'foldVersionRange' or 'toVersionIntervals'" #-}
{-# DEPRECATED WildcardVersion "use 'anyVersion', 'foldVersionRange' or 'toVersionIntervals'" #-}
{-# DEPRECATED UnionVersionRanges "use 'unionVersionRanges', 'foldVersionRange' or 'toVersionIntervals'" #-}
{-# DEPRECATED IntersectVersionRanges "use 'intersectVersionRanges', 'foldVersionRange' or 'toVersionIntervals'" #-}
-- | This is the converse of 'isAnyVersion'. It check if the version range is
-- empty, if there is no possible version that satisfies the version range.
--
-- For example this is @True@ (for all @v@):
--
-- > isNoVersion (EarlierVersion v `IntersectVersionRanges` LaterVersion v)
--
isNoVersion :: VersionRange -> Bool
isNoVersion vr = case toVersionIntervals vr of
VersionIntervals [] -> True
_ -> False
anyVersion :: VersionRange
anyVersion = AnyVersion
noVersion :: VersionRange
noVersion = IntersectVersionRanges (LaterVersion v) (EarlierVersion v)
where v = Version [1] []
thisVersion :: Version -> VersionRange
thisVersion = ThisVersion
notThisVersion :: Version -> VersionRange
notThisVersion v = UnionVersionRanges (EarlierVersion v) (LaterVersion v)
laterVersion :: Version -> VersionRange
laterVersion = LaterVersion
orLaterVersion :: Version -> VersionRange
orLaterVersion v = UnionVersionRanges (ThisVersion v) (LaterVersion v)
earlierVersion :: Version -> VersionRange
earlierVersion = EarlierVersion
orEarlierVersion :: Version -> VersionRange
orEarlierVersion v = UnionVersionRanges (ThisVersion v) (EarlierVersion v)
unionVersionRanges :: VersionRange -> VersionRange -> VersionRange
unionVersionRanges = UnionVersionRanges
intersectVersionRanges :: VersionRange -> VersionRange -> VersionRange
intersectVersionRanges = IntersectVersionRanges
betweenVersionsInclusive :: Version -> Version -> VersionRange
betweenVersionsInclusive v1 v2 =
......@@ -138,7 +148,7 @@ foldVersionRange :: a -> (Version -> a) -> (Version -> a) -> (Version -> a)
-> (Version -> Version -> a)
-> (a -> a -> a) -> (a -> a -> a)
-> VersionRange -> a
foldVersionRange anyv this later earlier wildcard union intersection = fold
foldVersionRange anyv this later earlier wildcard union intersect = fold
where
fold AnyVersion = anyv
fold (ThisVersion v) = this v
......@@ -146,7 +156,7 @@ foldVersionRange anyv this later earlier wildcard union intersection = fold
fold (EarlierVersion v) = earlier v
fold (WildcardVersion v) = wildcard v (wildcardUpperBound v)
fold (UnionVersionRanges v1 v2) = union (fold v1) (fold v2)
fold (IntersectVersionRanges v1 v2) = intersection (fold v1) (fold v2)
fold (IntersectVersionRanges v1 v2) = intersect (fold v1) (fold v2)
-- | Does this version fall within the given range?
--
......@@ -163,12 +173,49 @@ withinRange v = foldVersionRange
(||)
(&&)
-- | Does this 'VersionRange' place any restriction on the 'Version' or is it
-- in fact equivalent to 'AnyVersion'.
--
-- Note this is a semantic check, not simply a syntactic check. So for example
-- the following is @True@ (for all @v@).
--
-- > isAnyVersion (EarlierVersion v `UnionVersionRanges` orLaterVersion v)
--
isAnyVersion :: VersionRange -> Bool
isAnyVersion vr = case toVersionIntervals vr of
VersionIntervals [(NoLowerBound, NoUpperBound)] -> True
_ -> False
-- | This is the converse of 'isAnyVersion'. It check if the version range is
-- empty, if there is no possible version that satisfies the version range.
--
-- For example this is @True@ (for all @v@):
--
-- > isNoVersion (EarlierVersion v `IntersectVersionRanges` LaterVersion v)
--
isNoVersion :: VersionRange -> Bool
isNoVersion vr = case toVersionIntervals vr of
VersionIntervals [] -> True
_ -> False
-- | Is this version range in fact just a specific version?
--
-- For example the version range @\">= 3 && <= 3\"@ contains only the version
-- @3@.
--
isSpecificVersion :: VersionRange -> Maybe Version
isSpecificVersion vr = case toVersionIntervals vr of
VersionIntervals [(LowerBound v InclusiveBound
,UpperBound v' InclusiveBound)]
| v == v' -> Just v
_ -> Nothing
-- | Simplify a 'VersionRange' expression into a canonical form.
--
-- It just uses @fromVersionIntervals . toVersionIntervals@
--
simplify :: VersionRange -> VersionRange
simplify = fromVersionIntervals . toVersionIntervals
simplifyVersionRange :: VersionRange -> VersionRange
simplifyVersionRange = fromVersionIntervals . toVersionIntervals
----------------------------
-- Wildcard range utilities
......@@ -290,7 +337,7 @@ fromVersionIntervals (VersionIntervals intervals) =
interval (LowerBound v InclusiveBound)
(UpperBound v' ExclusiveBound) | isWildcardRange v v'
= WildcardVersion v
interval l u = lowerBound l `intersectVersionRanges` upperBound u
interval l u = lowerBound l `intersectVersionRanges'` upperBound u
lowerBound NoLowerBound = AnyVersion
lowerBound (LowerBound v InclusiveBound) = orLaterVersion v
......@@ -300,9 +347,9 @@ fromVersionIntervals (VersionIntervals intervals) =
upperBound (UpperBound v InclusiveBound) = orEarlierVersion v
upperBound (UpperBound v ExclusiveBound) = EarlierVersion v
intersectVersionRanges vr AnyVersion = vr
intersectVersionRanges AnyVersion vr = vr
intersectVersionRanges vr vr' = IntersectVersionRanges vr vr'
intersectVersionRanges' vr AnyVersion = vr
intersectVersionRanges' AnyVersion vr = vr
intersectVersionRanges' vr vr' = IntersectVersionRanges vr vr'
unionInterval :: VersionInterval -> VersionInterval
-> Either (Maybe VersionInterval) (Maybe VersionInterval)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment