module Distribution.Version (
Version(..),
VersionRange(..),
anyVersion, noVersion,
thisVersion, notThisVersion,
laterVersion, earlierVersion,
orLaterVersion, orEarlierVersion,
unionVersionRanges, intersectVersionRanges,
withinVersion,
betweenVersionsInclusive,
withinRange,
isAnyVersion,
isNoVersion,
isSpecificVersion,
simplifyVersionRange,
foldVersionRange,
foldVersionRange',
asVersionIntervals,
VersionInterval,
LowerBound(..),
UpperBound(..),
Bound(..),
VersionIntervals,
toVersionIntervals,
fromVersionIntervals,
withinIntervals,
versionIntervals,
mkVersionIntervals,
unionVersionIntervals,
intersectVersionIntervals,
) where
import Data.Version ( Version(..) )
import Distribution.Text ( Text(..) )
import qualified Distribution.Compat.ReadP as Parse
import Distribution.Compat.ReadP ((+++))
import qualified Text.PrettyPrint as Disp
import Text.PrettyPrint ((<>), (<+>))
import qualified Data.Char as Char (isDigit)
import Control.Exception (assert)
data VersionRange
= AnyVersion
| ThisVersion Version
| LaterVersion Version
| EarlierVersion Version
| WildcardVersion Version
| UnionVersionRanges VersionRange VersionRange
| IntersectVersionRanges VersionRange VersionRange
| VersionRangeParens VersionRange
deriving (D:Show ::
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow,D:Read ::
(Int -> ReadS a)
-> ReadS [a]
-> ReadPrec a
-> ReadPrec [a]
-> T:Read aRead,D:Eq :: (a -> a -> Bool) -> (a -> a -> Bool) -> T:Eq aEq)
anyVersion :: VersionRange
anyVersion = AnyVersion :: VersionRangeAnyVersion
noVersion :: VersionRange
noVersion = IntersectVersionRanges ::
VersionRange -> VersionRange -> VersionRangeIntersectVersionRanges (LaterVersion :: Version -> VersionRangeLaterVersion v :: Versionv) (EarlierVersion :: Version -> VersionRangeEarlierVersion v :: Versionv)
where v = Version :: [Int] -> [String] -> VersionVersion [1] [] :: [a][]
thisVersion :: Version -> VersionRange
thisVersion = ThisVersion :: Version -> VersionRangeThisVersion
notThisVersion :: Version -> VersionRange
notThisVersion v = UnionVersionRanges :: VersionRange -> VersionRange -> VersionRangeUnionVersionRanges (EarlierVersion :: Version -> VersionRangeEarlierVersion v :: Versionv) (LaterVersion :: Version -> VersionRangeLaterVersion v :: Versionv)
laterVersion :: Version -> VersionRange
laterVersion = LaterVersion :: Version -> VersionRangeLaterVersion
orLaterVersion :: Version -> VersionRange
orLaterVersion v = UnionVersionRanges :: VersionRange -> VersionRange -> VersionRangeUnionVersionRanges (ThisVersion :: Version -> VersionRangeThisVersion v :: Versionv) (LaterVersion :: Version -> VersionRangeLaterVersion v :: Versionv)
earlierVersion :: Version -> VersionRange
earlierVersion = EarlierVersion :: Version -> VersionRangeEarlierVersion
orEarlierVersion :: Version -> VersionRange
orEarlierVersion v = UnionVersionRanges :: VersionRange -> VersionRange -> VersionRangeUnionVersionRanges (ThisVersion :: Version -> VersionRangeThisVersion v :: Versionv) (EarlierVersion :: Version -> VersionRangeEarlierVersion v :: Versionv)
unionVersionRanges :: VersionRange -> VersionRange -> VersionRange
unionVersionRanges = UnionVersionRanges :: VersionRange -> VersionRange -> VersionRangeUnionVersionRanges
intersectVersionRanges :: VersionRange -> VersionRange -> VersionRange
intersectVersionRanges = IntersectVersionRanges ::
VersionRange -> VersionRange -> VersionRangeIntersectVersionRanges
withinVersion :: Version -> VersionRange
withinVersion = WildcardVersion :: Version -> VersionRangeWildcardVersion
betweenVersionsInclusive :: Version -> Version -> VersionRange
betweenVersionsInclusive v1 v2 =
IntersectVersionRanges ::
VersionRange -> VersionRange -> VersionRangeIntersectVersionRanges (orLaterVersion :: Version -> VersionRangeorLaterVersion v1 :: VersionRangev1) (orEarlierVersion :: Version -> VersionRangeorEarlierVersion v2 :: VersionRangev2)
foldVersionRange :: a
-> (Version -> a)
-> (Version -> a)
-> (Version -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> VersionRange -> a
foldVersionRange anyv this later earlier union intersect = fold :: VersionRange -> afold
where
fold AnyVersion = anyv :: aanyv
fold (ThisVersion v) = this :: Version -> athis v :: Versionv
fold (LaterVersion v) = later :: Version -> alater v :: Versionv
fold (EarlierVersion v) = earlier :: Version -> aearlier v :: Versionv
fold (WildcardVersion v) = fold :: VersionRange -> afold (wildcard :: Version -> VersionRangewildcard v :: Versionv)
fold (UnionVersionRanges v1 v2) = union :: a -> a -> aunion (fold :: VersionRange -> afold v1 :: VersionRangev1) (fold :: VersionRange -> afold v2 :: VersionRangev2)
fold (IntersectVersionRanges v1 v2) = intersect :: a -> a -> aintersect (fold :: VersionRange -> afold v1 :: VersionRangev1) (fold :: VersionRange -> afold v2 :: VersionRangev2)
fold (VersionRangeParens v) = fold :: VersionRange -> afold v :: Versionv
wildcard v = intersectVersionRanges ::
VersionRange -> VersionRange -> VersionRangeintersectVersionRanges
(orLaterVersion :: Version -> VersionRangeorLaterVersion v :: Versionv)
(earlierVersion :: Version -> VersionRangeearlierVersion (wildcardUpperBound :: Version -> VersionwildcardUpperBound v :: Versionv))
foldVersionRange' :: a
-> (Version -> a)
-> (Version -> a)
-> (Version -> a)
-> (Version -> a)
-> (Version -> a)
-> (Version -> Version -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> VersionRange -> a
foldVersionRange' anyv this later earlier orLater orEarlier
wildcard union intersect parens = fold :: VersionRange -> afold
where
fold AnyVersion = anyv :: aanyv
fold (ThisVersion v) = this :: Version -> athis v :: Versionv
fold (LaterVersion v) = later :: Version -> alater v :: Versionv
fold (EarlierVersion v) = earlier :: Version -> aearlier v :: Versionv
fold (UnionVersionRanges (ThisVersion v)
(LaterVersion v')) | v :: Versionv(==) :: Eq a => a -> a -> Bool==v' :: Versionv' = orLater :: Version -> aorLater v :: Versionv
fold (UnionVersionRanges (LaterVersion v)
(ThisVersion v')) | v :: Versionv(==) :: Eq a => a -> a -> Bool==v' :: Versionv' = orLater :: Version -> aorLater v :: Versionv
fold (UnionVersionRanges (ThisVersion v)
(EarlierVersion v')) | v :: Versionv(==) :: Eq a => a -> a -> Bool==v' :: Versionv' = orEarlier :: Version -> aorEarlier v :: Versionv
fold (UnionVersionRanges (EarlierVersion v)
(ThisVersion v')) | v :: Versionv(==) :: Eq a => a -> a -> Bool==v' :: Versionv' = orEarlier :: Version -> aorEarlier v :: Versionv
fold (WildcardVersion v) = wildcard :: Version -> VersionRangewildcard v :: Versionv (wildcardUpperBound :: Version -> VersionwildcardUpperBound v :: Versionv)
fold (UnionVersionRanges v1 v2) = union :: a -> a -> aunion (fold :: VersionRange -> afold v1 :: VersionRangev1) (fold :: VersionRange -> afold v2 :: VersionRangev2)
fold (IntersectVersionRanges v1 v2) = intersect :: a -> a -> aintersect (fold :: VersionRange -> afold v1 :: VersionRangev1) (fold :: VersionRange -> afold v2 :: VersionRangev2)
fold (VersionRangeParens v) = parens :: Parser r Char VersionRange -> ReadP r VersionRangeparens (fold :: VersionRange -> afold v :: Versionv)
withinRange :: Version -> VersionRange -> Bool
withinRange v = foldVersionRange ::
a
-> (Version -> a)
-> (Version -> a)
-> (Version -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> VersionRange
-> afoldVersionRange
True :: BoolTrue
(\v' -> versionBranch :: Version -> [Int]versionBranch v :: Versionv (==) :: Eq a => a -> a -> Bool== versionBranch :: Version -> [Int]versionBranch v' :: Versionv')
(\v' -> versionBranch :: Version -> [Int]versionBranch v :: Versionv (>) :: Ord a => a -> a -> Bool> versionBranch :: Version -> [Int]versionBranch v' :: Versionv')
(\v' -> versionBranch :: Version -> [Int]versionBranch v :: Versionv (<) :: Ord a => a -> a -> Bool< versionBranch :: Version -> [Int]versionBranch v' :: Versionv')
(||) :: Bool -> Bool -> Bool(||)
(&&) :: Bool -> Bool -> Bool(&&)
asVersionIntervals :: VersionRange -> [VersionInterval]
asVersionIntervals = versionIntervals :: VersionIntervals -> [VersionInterval]versionIntervals (.) :: (b -> c) -> (a -> b) -> a -> c. toVersionIntervals :: VersionRange -> VersionIntervalstoVersionIntervals
isAnyVersion :: VersionRange -> Bool
isAnyVersion vr = case asVersionIntervals :: VersionRange -> [VersionInterval]asVersionIntervals vr :: VersionRangevr of
[(LowerBound v InclusiveBound, NoUpperBound)] | isVersion0 :: Version -> BoolisVersion0 v :: Versionv -> True :: BoolTrue
_ -> False :: BoolFalse
isNoVersion :: VersionRange -> Bool
isNoVersion vr = case asVersionIntervals :: VersionRange -> [VersionInterval]asVersionIntervals vr :: VersionRangevr of
[] -> True :: BoolTrue
_ -> False :: BoolFalse
isSpecificVersion :: VersionRange -> Maybe Version
isSpecificVersion vr = case asVersionIntervals :: VersionRange -> [VersionInterval]asVersionIntervals vr :: VersionRangevr of
[(LowerBound v InclusiveBound
,UpperBound v' InclusiveBound)]
| v :: Versionv (==) :: Eq a => a -> a -> Bool== v' :: Versionv' -> Just :: a -> Maybe aJust v :: Versionv
_ -> Nothing :: Maybe aNothing
simplifyVersionRange :: VersionRange -> VersionRange
simplifyVersionRange vr
| null :: [a] -> Boolnull (versionIntervals :: VersionIntervals -> [VersionInterval]versionIntervals vi :: VersionIntervalsvi) = vr :: VersionRangevr
| otherwise :: Boolotherwise = fromVersionIntervals :: VersionIntervals -> VersionRangefromVersionIntervals vi :: VersionIntervalsvi
where
vi = toVersionIntervals :: VersionRange -> VersionIntervalstoVersionIntervals vr :: VersionRangevr
wildcardUpperBound :: Version -> Version
wildcardUpperBound (Version lowerBound ts) = (Version :: [Int] -> [String] -> VersionVersion upperBound :: UpperBound -> VersionRangeupperBound ts :: [String]ts)
where
upperBound = init :: [a] -> [a]init lowerBound :: LowerBound -> VersionRangelowerBound (++) :: [a] -> [a] -> [a]++ [last :: [a] -> alast lowerBound :: LowerBound -> VersionRangelowerBound (+) :: Num a => a -> a -> a+ 1]
isWildcardRange :: Version -> Version -> Bool
isWildcardRange (Version branch1 _) (Version branch2 _) = check :: [a] -> [a] -> Boolcheck branch1 :: [Int]branch1 branch2 :: [Int]branch2
where check (n:[]) (m:[]) | n :: an(+) :: Num a => a -> a -> a+1 (==) :: Eq a => a -> a -> Bool== m :: am = True :: BoolTrue
check (n:ns) (m:ms) | n :: an (==) :: Eq a => a -> a -> Bool== m :: am = check :: [a] -> [a] -> Boolcheck ns :: [a]ns ms :: [a]ms
check _ _ = False :: BoolFalse
newtype VersionIntervals = VersionIntervals [VersionInterval]
deriving (D:Eq :: (a -> a -> Bool) -> (a -> a -> Bool) -> T:Eq aEq, D:Show ::
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow)
versionIntervals :: VersionIntervals -> [VersionInterval]
versionIntervals (VersionIntervals is) = is :: [VersionInterval]is
type VersionInterval = (LowerBound, UpperBound)
data LowerBound = LowerBound Version !Bound deriving (D:Eq :: (a -> a -> Bool) -> (a -> a -> Bool) -> T:Eq aEq, D:Show ::
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow)
data UpperBound = NoUpperBound | UpperBound Version !Bound deriving (D:Eq :: (a -> a -> Bool) -> (a -> a -> Bool) -> T:Eq aEq, D:Show ::
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow)
data Bound = ExclusiveBound | InclusiveBound deriving (D:Eq :: (a -> a -> Bool) -> (a -> a -> Bool) -> T:Eq aEq, D:Show ::
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow)
minLowerBound :: LowerBound
minLowerBound = ($WLowerBound) :: Version -> Bound -> LowerBoundLowerBound (Version :: [Int] -> [String] -> VersionVersion [0] [] :: [a][]) InclusiveBound :: BoundInclusiveBound
isVersion0 :: Version -> Bool
isVersion0 (Version [0] _) = True :: BoolTrue
isVersion0 _ = False :: BoolFalse
instance D:Ord ::
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> T:Ord aOrd LowerBound where
LowerBound ver bound <= LowerBound ver' bound' = case compare :: Ord a => a -> a -> Orderingcompare ver :: Versionver ver' :: Versionver' of
LT -> True :: BoolTrue
EQ -> not :: Bool -> Boolnot (bound :: Boundbound (==) :: Eq a => a -> a -> Bool== ExclusiveBound :: BoundExclusiveBound (&&) :: Bool -> Bool -> Bool&& bound' :: Boundbound' (==) :: Eq a => a -> a -> Bool== InclusiveBound :: BoundInclusiveBound)
GT -> False :: BoolFalse
instance D:Ord ::
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> T:Ord aOrd UpperBound where
_ <= NoUpperBound = True :: BoolTrue
NoUpperBound <= UpperBound _ _ = False :: BoolFalse
UpperBound ver bound <= UpperBound ver' bound' = case compare :: Ord a => a -> a -> Orderingcompare ver :: Versionver ver' :: Versionver' of
LT -> True :: BoolTrue
EQ -> not :: Bool -> Boolnot (bound :: Boundbound (==) :: Eq a => a -> a -> Bool== InclusiveBound :: BoundInclusiveBound (&&) :: Bool -> Bool -> Bool&& bound' :: Boundbound' (==) :: Eq a => a -> a -> Bool== ExclusiveBound :: BoundExclusiveBound)
GT -> False :: BoolFalse
invariant :: VersionIntervals -> Bool
invariant (VersionIntervals intervals) = all :: (a -> Bool) -> [a] -> Boolall validInterval :: (LowerBound, UpperBound) -> BoolvalidInterval intervals :: [VersionInterval]intervals
(&&) :: Bool -> Bool -> Bool&& all :: (a -> Bool) -> [a] -> Boolall doesNotTouch' :: (VersionInterval, VersionInterval) -> BooldoesNotTouch' adjacentIntervals :: [(VersionInterval, VersionInterval)]adjacentIntervals
where
doesNotTouch' :: (VersionInterval, VersionInterval) -> Bool
doesNotTouch' ((_,u), (l',_)) = doesNotTouch :: UpperBound -> LowerBound -> BooldoesNotTouch u :: UpperBoundu l' :: LowerBoundl'
adjacentIntervals :: [(VersionInterval, VersionInterval)]
adjacentIntervals
| null :: [a] -> Boolnull intervals :: [VersionInterval]intervals = [] :: [a][]
| otherwise :: Boolotherwise = zip :: [a] -> [b] -> [(a, b)]zip intervals :: [VersionInterval]intervals (tail :: [a] -> [a]tail intervals :: [VersionInterval]intervals)
checkInvariant :: VersionIntervals -> VersionIntervals
checkInvariant is = assertError :: Addr# -> Bool -> a -> aassert (invariant :: VersionIntervals -> Boolinvariant is :: [VersionInterval]is) is :: [VersionInterval]is
mkVersionIntervals :: [VersionInterval] -> Maybe VersionIntervals
mkVersionIntervals intervals
| invariant :: VersionIntervals -> Boolinvariant (VersionIntervals :: [VersionInterval] -> VersionIntervalsVersionIntervals intervals :: [VersionInterval]intervals) = Just :: a -> Maybe aJust (VersionIntervals :: [VersionInterval] -> VersionIntervalsVersionIntervals intervals :: [VersionInterval]intervals)
| otherwise :: Boolotherwise = Nothing :: Maybe aNothing
validVersion :: Version -> Bool
validVersion (Version [] _) = False :: BoolFalse
validVersion (Version vs _) = all :: (a -> Bool) -> [a] -> Boolall ((>=) :: Ord a => a -> a -> Bool>=0) vs :: [Int]vs
validInterval :: (LowerBound, UpperBound) -> Bool
validInterval i@(l, u) = validLower :: LowerBound -> BoolvalidLower l :: LowerBoundl (&&) :: Bool -> Bool -> Bool&& validUpper :: UpperBound -> BoolvalidUpper u :: UpperBoundu (&&) :: Bool -> Bool -> Bool&& nonEmpty :: VersionInterval -> BoolnonEmpty i :: VersionIntervali
where
validLower (LowerBound v _) = validVersion :: Version -> BoolvalidVersion v :: Versionv
validUpper NoUpperBound = True :: BoolTrue
validUpper (UpperBound v _) = validVersion :: Version -> BoolvalidVersion v :: Versionv
nonEmpty :: VersionInterval -> Bool
nonEmpty (_, NoUpperBound ) = True :: BoolTrue
nonEmpty (LowerBound l lb, UpperBound u ub) =
(l :: LowerBoundl (<) :: Ord a => a -> a -> Bool< u :: UpperBoundu) (||) :: Bool -> Bool -> Bool|| (l :: LowerBoundl (==) :: Eq a => a -> a -> Bool== u :: UpperBoundu (&&) :: Bool -> Bool -> Bool&& lb :: Boundlb (==) :: Eq a => a -> a -> Bool== InclusiveBound :: BoundInclusiveBound (&&) :: Bool -> Bool -> Bool&& ub :: Boundub (==) :: Eq a => a -> a -> Bool== InclusiveBound :: BoundInclusiveBound)
doesNotTouch :: UpperBound -> LowerBound -> Bool
doesNotTouch NoUpperBound _ = False :: BoolFalse
doesNotTouch (UpperBound u ub) (LowerBound l lb) =
u :: UpperBoundu (<) :: Ord a => a -> a -> Bool< l :: LowerBoundl
(||) :: Bool -> Bool -> Bool|| (u :: UpperBoundu (==) :: Eq a => a -> a -> Bool== l :: LowerBoundl (&&) :: Bool -> Bool -> Bool&& ub :: Boundub (==) :: Eq a => a -> a -> Bool== ExclusiveBound :: BoundExclusiveBound (&&) :: Bool -> Bool -> Bool&& lb :: Boundlb (==) :: Eq a => a -> a -> Bool== ExclusiveBound :: BoundExclusiveBound)
doesNotIntersect :: UpperBound -> LowerBound -> Bool
doesNotIntersect NoUpperBound _ = False :: BoolFalse
doesNotIntersect (UpperBound u ub) (LowerBound l lb) =
u :: UpperBoundu (<) :: Ord a => a -> a -> Bool< l :: LowerBoundl
(||) :: Bool -> Bool -> Bool|| (u :: UpperBoundu (==) :: Eq a => a -> a -> Bool== l :: LowerBoundl (&&) :: Bool -> Bool -> Bool&& not :: Bool -> Boolnot (ub :: Boundub (==) :: Eq a => a -> a -> Bool== InclusiveBound :: BoundInclusiveBound (&&) :: Bool -> Bool -> Bool&& lb :: Boundlb (==) :: Eq a => a -> a -> Bool== InclusiveBound :: BoundInclusiveBound))
withinIntervals :: Version -> VersionIntervals -> Bool
withinIntervals v (VersionIntervals intervals) = any :: (a -> Bool) -> [a] -> Boolany withinInterval :: (LowerBound, UpperBound) -> BoolwithinInterval intervals :: [VersionInterval]intervals
where
withinInterval (lowerBound, upperBound) = withinLower :: LowerBound -> BoolwithinLower lowerBound :: LowerBound -> VersionRangelowerBound
(&&) :: Bool -> Bool -> Bool&& withinUpper :: UpperBound -> BoolwithinUpper upperBound :: UpperBound -> VersionRangeupperBound
withinLower (LowerBound v' ExclusiveBound) = v' :: Versionv' (<) :: Ord a => a -> a -> Bool< v :: Versionv
withinLower (LowerBound v' InclusiveBound) = v' :: Versionv' (<=) :: Ord a => a -> a -> Bool<= v :: Versionv
withinUpper NoUpperBound = True :: BoolTrue
withinUpper (UpperBound v' ExclusiveBound) = v' :: Versionv' (>) :: Ord a => a -> a -> Bool> v :: Versionv
withinUpper (UpperBound v' InclusiveBound) = v' :: Versionv' (>=) :: Ord a => a -> a -> Bool>= v :: Versionv
toVersionIntervals :: VersionRange -> VersionIntervals
toVersionIntervals = foldVersionRange ::
a
-> (Version -> a)
-> (Version -> a)
-> (Version -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> VersionRange
-> afoldVersionRange
( chkIvl :: VersionInterval -> VersionIntervalschkIvl (minLowerBound :: LowerBoundminLowerBound, NoUpperBound :: UpperBoundNoUpperBound))
(\v -> chkIvl :: VersionInterval -> VersionIntervalschkIvl (($WLowerBound) :: Version -> Bound -> LowerBoundLowerBound v :: Versionv InclusiveBound :: BoundInclusiveBound, ($WUpperBound) :: Version -> Bound -> UpperBoundUpperBound v :: Versionv InclusiveBound :: BoundInclusiveBound))
(\v -> chkIvl :: VersionInterval -> VersionIntervalschkIvl (($WLowerBound) :: Version -> Bound -> LowerBoundLowerBound v :: Versionv ExclusiveBound :: BoundExclusiveBound, NoUpperBound :: UpperBoundNoUpperBound))
(\v -> if isVersion0 :: Version -> BoolisVersion0 v :: Versionv then VersionIntervals :: [VersionInterval] -> VersionIntervalsVersionIntervals [] :: [a][] else
chkIvl :: VersionInterval -> VersionIntervalschkIvl (minLowerBound :: LowerBoundminLowerBound, ($WUpperBound) :: Version -> Bound -> UpperBoundUpperBound v :: Versionv ExclusiveBound :: BoundExclusiveBound))
unionVersionIntervals ::
VersionIntervals -> VersionIntervals -> VersionIntervalsunionVersionIntervals
intersectVersionIntervals ::
VersionIntervals -> VersionIntervals -> VersionIntervalsintersectVersionIntervals
where
chkIvl interval = checkInvariant :: VersionIntervals -> VersionIntervalscheckInvariant (VersionIntervals :: [VersionInterval] -> VersionIntervalsVersionIntervals [interval :: LowerBound -> UpperBound -> VersionRangeinterval])
fromVersionIntervals :: VersionIntervals -> VersionRange
fromVersionIntervals (VersionIntervals []) = noVersion :: VersionRangenoVersion
fromVersionIntervals (VersionIntervals intervals) =
foldr1 :: (a -> a -> a) -> [a] -> afoldr1 UnionVersionRanges :: VersionRange -> VersionRange -> VersionRangeUnionVersionRanges [ interval :: LowerBound -> UpperBound -> VersionRangeinterval l :: LowerBoundl u :: UpperBoundu | (l, u) <- intervals :: [VersionInterval]intervals ]
where
interval (LowerBound v InclusiveBound)
(UpperBound v' InclusiveBound) | v :: Versionv (==) :: Eq a => a -> a -> Bool== v' :: Versionv'
= ThisVersion :: Version -> VersionRangeThisVersion v :: Versionv
interval (LowerBound v InclusiveBound)
(UpperBound v' ExclusiveBound) | isWildcardRange :: Version -> Version -> BoolisWildcardRange v :: Versionv v' :: Versionv'
= WildcardVersion :: Version -> VersionRangeWildcardVersion v :: Versionv
interval l u = lowerBound :: LowerBound -> VersionRangelowerBound l :: LowerBoundl intersectVersionRanges' ::
VersionRange -> VersionRange -> VersionRange`intersectVersionRanges'` upperBound :: UpperBound -> VersionRangeupperBound u :: UpperBoundu
lowerBound (LowerBound v InclusiveBound)
| isVersion0 :: Version -> BoolisVersion0 v :: Versionv = AnyVersion :: VersionRangeAnyVersion
| otherwise :: Boolotherwise = orLaterVersion :: Version -> VersionRangeorLaterVersion v :: Versionv
lowerBound (LowerBound v ExclusiveBound) = LaterVersion :: Version -> VersionRangeLaterVersion v :: Versionv
upperBound NoUpperBound = AnyVersion :: VersionRangeAnyVersion
upperBound (UpperBound v InclusiveBound) = orEarlierVersion :: Version -> VersionRangeorEarlierVersion v :: Versionv
upperBound (UpperBound v ExclusiveBound) = EarlierVersion :: Version -> VersionRangeEarlierVersion v :: Versionv
intersectVersionRanges' vr AnyVersion = vr :: VersionRangevr
intersectVersionRanges' AnyVersion vr = vr :: VersionRangevr
intersectVersionRanges' vr vr' = IntersectVersionRanges ::
VersionRange -> VersionRange -> VersionRangeIntersectVersionRanges vr :: VersionRangevr vr' :: VersionRangevr'
unionVersionIntervals :: VersionIntervals -> VersionIntervals
-> VersionIntervals
unionVersionIntervals (VersionIntervals is0) (VersionIntervals is'0) =
checkInvariant :: VersionIntervals -> VersionIntervalscheckInvariant (VersionIntervals :: [VersionInterval] -> VersionIntervalsVersionIntervals (union :: a -> a -> aunion is0 :: [VersionInterval]is0 is'0 :: [VersionInterval]is'0))
where
union is [] = is :: [VersionInterval]is
union [] is' = is' :: [VersionInterval]is'
union (i:is) (i':is') = case unionInterval ::
VersionInterval
-> VersionInterval
-> Either (Maybe VersionInterval) (Maybe VersionInterval)unionInterval i :: VersionIntervali i' :: VersionIntervali' of
Left Nothing -> i :: VersionIntervali (:) :: a -> [a] -> [a]: union :: a -> a -> aunion is :: [VersionInterval]is (i' :: VersionIntervali' (:) :: a -> [a] -> [a]:is' :: [VersionInterval]is')
Left (Just i'') -> union :: a -> a -> aunion is :: [VersionInterval]is (i'' :: VersionIntervali''(:) :: a -> [a] -> [a]:is' :: [VersionInterval]is')
Right Nothing -> i' :: VersionIntervali' (:) :: a -> [a] -> [a]: union :: a -> a -> aunion (i :: VersionIntervali (:) :: a -> [a] -> [a]:is :: [VersionInterval]is) is' :: [VersionInterval]is'
Right (Just i'') -> union :: a -> a -> aunion (i'' :: VersionIntervali''(:) :: a -> [a] -> [a]:is :: [VersionInterval]is) is' :: [VersionInterval]is'
unionInterval :: VersionInterval -> VersionInterval
-> Either (Maybe VersionInterval) (Maybe VersionInterval)
unionInterval (lower , upper ) (lower', upper')
| upper :: UpperBoundupper doesNotTouch :: UpperBound -> LowerBound -> Bool`doesNotTouch` lower' :: LowerBoundlower' = Left :: a -> Either a bLeft Nothing :: Maybe aNothing
| upper' :: UpperBoundupper' doesNotTouch :: UpperBound -> LowerBound -> Bool`doesNotTouch` lower :: LowerBoundlower = Right :: b -> Either a bRight Nothing :: Maybe aNothing
| upper :: UpperBoundupper (<=) :: Ord a => a -> a -> Bool<= upper' :: UpperBoundupper' = lowerBound :: LowerBound -> VersionRangelowerBound seq :: a -> b -> b`seq`
Left :: a -> Either a bLeft (Just :: a -> Maybe aJust (lowerBound :: LowerBound -> VersionRangelowerBound, upper' :: UpperBoundupper'))
| otherwise :: Boolotherwise = lowerBound :: LowerBound -> VersionRangelowerBound seq :: a -> b -> b`seq`
Right :: b -> Either a bRight (Just :: a -> Maybe aJust (lowerBound :: LowerBound -> VersionRangelowerBound, upper :: UpperBoundupper))
where
lowerBound = min :: Ord a => a -> a -> amin lower :: LowerBoundlower lower' :: LowerBoundlower'
intersectVersionIntervals :: VersionIntervals -> VersionIntervals
-> VersionIntervals
intersectVersionIntervals (VersionIntervals is0) (VersionIntervals is'0) =
checkInvariant :: VersionIntervals -> VersionIntervalscheckInvariant (VersionIntervals :: [VersionInterval] -> VersionIntervalsVersionIntervals (intersect :: a -> a -> aintersect is0 :: [VersionInterval]is0 is'0 :: [VersionInterval]is'0))
where
intersect _ [] = [] :: [a][]
intersect [] _ = [] :: [a][]
intersect (i:is) (i':is') = case intersectInterval ::
VersionInterval
-> VersionInterval
-> Either (Maybe VersionInterval) (Maybe VersionInterval)intersectInterval i :: VersionIntervali i' :: VersionIntervali' of
Left Nothing -> intersect :: a -> a -> aintersect is :: [VersionInterval]is (i' :: VersionIntervali'(:) :: a -> [a] -> [a]:is' :: [VersionInterval]is')
Left (Just i'') -> i'' :: VersionIntervali'' (:) :: a -> [a] -> [a]: intersect :: a -> a -> aintersect is :: [VersionInterval]is (i' :: VersionIntervali'(:) :: a -> [a] -> [a]:is' :: [VersionInterval]is')
Right Nothing -> intersect :: a -> a -> aintersect (i :: VersionIntervali(:) :: a -> [a] -> [a]:is :: [VersionInterval]is) is' :: [VersionInterval]is'
Right (Just i'') -> i'' :: VersionIntervali'' (:) :: a -> [a] -> [a]: intersect :: a -> a -> aintersect (i :: VersionIntervali(:) :: a -> [a] -> [a]:is :: [VersionInterval]is) is' :: [VersionInterval]is'
intersectInterval :: VersionInterval -> VersionInterval
-> Either (Maybe VersionInterval) (Maybe VersionInterval)
intersectInterval (lower , upper ) (lower', upper')
| upper :: UpperBoundupper doesNotIntersect :: UpperBound -> LowerBound -> Bool`doesNotIntersect` lower' :: LowerBoundlower' = Left :: a -> Either a bLeft Nothing :: Maybe aNothing
| upper' :: UpperBoundupper' doesNotIntersect :: UpperBound -> LowerBound -> Bool`doesNotIntersect` lower :: LowerBoundlower = Right :: b -> Either a bRight Nothing :: Maybe aNothing
| upper :: UpperBoundupper (<=) :: Ord a => a -> a -> Bool<= upper' :: UpperBoundupper' = lowerBound :: LowerBound -> VersionRangelowerBound seq :: a -> b -> b`seq`
Left :: a -> Either a bLeft (Just :: a -> Maybe aJust (lowerBound :: LowerBound -> VersionRangelowerBound, upper :: UpperBoundupper))
| otherwise :: Boolotherwise = lowerBound :: LowerBound -> VersionRangelowerBound seq :: a -> b -> b`seq`
Right :: b -> Either a bRight (Just :: a -> Maybe aJust (lowerBound :: LowerBound -> VersionRangelowerBound, upper' :: UpperBoundupper'))
where
lowerBound = max :: Ord a => a -> a -> amax lower :: LowerBoundlower lower' :: LowerBoundlower'
instance D:Text :: (a -> Doc) -> (forall r. ReadP r a) -> T:Text aText VersionRange where
disp = fst :: (a, b) -> afst
(.) :: (b -> c) -> (a -> b) -> a -> c. foldVersionRange' ::
a
-> (Version -> a)
-> (Version -> a)
-> (Version -> a)
-> (Version -> a)
-> (Version -> a)
-> (Version -> Version -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> VersionRange
-> afoldVersionRange'
( text :: String -> DocDisp.text "-any" , 0 :: Int)
(\v -> (text :: String -> DocDisp.text "==" (<>) :: Doc -> Doc -> Doc<> disp :: Text a => a -> Docdisp v :: Versionv , 0))
(\v -> (char :: Char -> DocDisp.char '>' (<>) :: Doc -> Doc -> Doc<> disp :: Text a => a -> Docdisp v :: Versionv , 0))
(\v -> (char :: Char -> DocDisp.char '<' (<>) :: Doc -> Doc -> Doc<> disp :: Text a => a -> Docdisp v :: Versionv , 0))
(\v -> (text :: String -> DocDisp.text ">=" (<>) :: Doc -> Doc -> Doc<> disp :: Text a => a -> Docdisp v :: Versionv , 0))
(\v -> (text :: String -> DocDisp.text "<=" (<>) :: Doc -> Doc -> Doc<> disp :: Text a => a -> Docdisp v :: Versionv , 0))
(\v _ -> (text :: String -> DocDisp.text "==" (<>) :: Doc -> Doc -> Doc<> dispWild :: Version -> DocdispWild v :: Versionv , 0))
(\(r1, p1) (r2, p2) -> (punct :: a -> a -> Doc -> Docpunct 2 p1 :: Intp1 r1 :: Docr1 (<+>) :: Doc -> Doc -> Doc<+> text :: String -> DocDisp.text "||" (<+>) :: Doc -> Doc -> Doc<+> punct :: a -> a -> Doc -> Docpunct 2 p2 :: Intp2 r2 :: Docr2 , 2))
(\(r1, p1) (r2, p2) -> (punct :: a -> a -> Doc -> Docpunct 1 p1 :: Intp1 r1 :: Docr1 (<+>) :: Doc -> Doc -> Doc<+> text :: String -> DocDisp.text "&&" (<+>) :: Doc -> Doc -> Doc<+> punct :: a -> a -> Doc -> Docpunct 1 p2 :: Intp2 r2 :: Docr2 , 1))
(\(r, p) -> (parens :: Doc -> DocDisp.parens r :: Docr, p :: Parser r Char VersionRangep))
where dispWild (Version b _) =
hcat :: [Doc] -> DocDisp.hcat (punctuate :: Doc -> [Doc] -> [Doc]Disp.punctuate (char :: Char -> DocDisp.char '.') (map :: (a -> b) -> [a] -> [b]map int :: Int -> DocDisp.int b :: [Int]b))
(<>) :: Doc -> Doc -> Doc<> text :: String -> DocDisp.text ".*"
punct p p' | p :: Parser r Char VersionRangep (<) :: Ord a => a -> a -> Bool< p' :: ap' = parens :: Doc -> DocDisp.parens
| otherwise :: Boolotherwise = id :: a -> aid
parse = expr :: Parser r Char VersionRangeexpr
where
expr = do skipSpaces :: ReadP r ()Parse.skipSpaces
t <- term :: Parser r Char VersionRangeterm
skipSpaces :: ReadP r ()Parse.skipSpaces
(do _ <- string :: String -> ReadP r StringParse.string "||"
skipSpaces :: ReadP r ()Parse.skipSpaces
e <- expr :: Parser r Char VersionRangeexpr
return :: Monad m => forall a. a -> m areturn (UnionVersionRanges :: VersionRange -> VersionRange -> VersionRangeUnionVersionRanges t :: VersionRanget e :: VersionRangee)
(+++) :: ReadP r a -> ReadP r a -> ReadP r a+++
return :: Monad m => forall a. a -> m areturn t :: VersionRanget)
term = do f <- factor :: Parser r Char VersionRangefactor
skipSpaces :: ReadP r ()Parse.skipSpaces
(do _ <- string :: String -> ReadP r StringParse.string "&&"
skipSpaces :: ReadP r ()Parse.skipSpaces
t <- term :: Parser r Char VersionRangeterm
return :: Monad m => forall a. a -> m areturn (IntersectVersionRanges ::
VersionRange -> VersionRange -> VersionRangeIntersectVersionRanges f :: VersionRangef t :: VersionRanget)
(+++) :: ReadP r a -> ReadP r a -> ReadP r a+++
return :: Monad m => forall a. a -> m areturn f :: VersionRangef)
factor = choice :: [ReadP r a] -> ReadP r aParse.choice ($) :: (a -> b) -> a -> b$ parens :: Parser r Char VersionRange -> ReadP r VersionRangeparens expr :: Parser r Char VersionRangeexpr
(:) :: a -> [a] -> [a]: parseAnyVersion :: Parser r Char VersionRangeparseAnyVersion
(:) :: a -> [a] -> [a]: parseWildcardRange :: Parser r Char VersionRangeparseWildcardRange
(:) :: a -> [a] -> [a]: map :: (a -> b) -> [a] -> [b]map parseRangeOp :: Text a => (String, a -> b) -> Parser r Char bparseRangeOp rangeOps :: [([Char], Version -> VersionRange)]rangeOps
parseAnyVersion = string :: String -> ReadP r StringParse.string "-any" (>>) :: Monad m => forall a b. m a -> m b -> m b>> return :: Monad m => forall a. a -> m areturn AnyVersion :: VersionRangeAnyVersion
parseWildcardRange = do
_ <- string :: String -> ReadP r StringParse.string "=="
skipSpaces :: ReadP r ()Parse.skipSpaces
branch <- sepBy1 :: ReadP r a -> ReadP r sep -> ReadP r [a]Parse.sepBy1 digits :: Parser r Char Intdigits (char :: Char -> ReadP r CharParse.char '.')
_ <- char :: Char -> ReadP r CharParse.char '.'
_ <- char :: Char -> ReadP r CharParse.char '*'
return :: Monad m => forall a. a -> m areturn (WildcardVersion :: Version -> VersionRangeWildcardVersion (Version :: [Int] -> [String] -> VersionVersion branch :: [Int]branch [] :: [a][]))
parens p = between :: ReadP r open -> ReadP r close -> ReadP r a -> ReadP r aParse.between (char :: Char -> ReadP r CharParse.char '(' (>>) :: Monad m => forall a b. m a -> m b -> m b>> skipSpaces :: ReadP r ()Parse.skipSpaces)
(char :: Char -> ReadP r CharParse.char ')' (>>) :: Monad m => forall a b. m a -> m b -> m b>> skipSpaces :: ReadP r ()Parse.skipSpaces)
(do a <- p :: Parser r Char VersionRangep
skipSpaces :: ReadP r ()Parse.skipSpaces
return :: Monad m => forall a. a -> m areturn (VersionRangeParens :: VersionRange -> VersionRangeVersionRangeParens a :: VersionRangea))
digits = do
first <- satisfy :: (Char -> Bool) -> ReadP r CharParse.satisfy isDigit :: Char -> BoolChar.isDigit
if first :: Charfirst (==) :: Eq a => a -> a -> Bool== '0'
then return :: Monad m => forall a. a -> m areturn 0
else do rest <- munch :: (Char -> Bool) -> ReadP r StringParse.munch isDigit :: Char -> BoolChar.isDigit
return :: Monad m => forall a. a -> m areturn (read :: Read a => String -> aread (first :: Charfirst (:) :: a -> [a] -> [a]: rest :: Stringrest))
parseRangeOp (s,f) = string :: String -> ReadP r StringParse.string s :: Strings (>>) :: Monad m => forall a b. m a -> m b -> m b>> skipSpaces :: ReadP r ()Parse.skipSpaces (>>) :: Monad m => forall a b. m a -> m b -> m b>> fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap f :: VersionRangef parse :: Text a => forall r. ReadP r aparse
rangeOps = [ ("<", EarlierVersion :: Version -> VersionRangeEarlierVersion),
("<=", orEarlierVersion :: Version -> VersionRangeorEarlierVersion),
(">", LaterVersion :: Version -> VersionRangeLaterVersion),
(">=", orLaterVersion :: Version -> VersionRangeorLaterVersion),
("==", ThisVersion :: Version -> VersionRangeThisVersion) ]