{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Distribution.Types.VersionInterval (
VersionIntervals,
unVersionIntervals,
toVersionIntervals,
fromVersionIntervals,
normaliseVersionRange2,
relaxLastInterval,
relaxHeadInterval,
asVersionIntervals,
VersionInterval (..),
LowerBound(..),
UpperBound(..),
Bound(..),
invariantVersionIntervals,
) where
import Control.Applicative (liftA2)
import Control.Exception (assert)
import Distribution.Compat.Prelude hiding (Applicative(..))
import Prelude ()
import Distribution.Types.Version
import Distribution.Types.VersionRange.Internal
newtype VersionIntervals = VersionIntervals [VersionInterval]
deriving (VersionIntervals -> VersionIntervals -> Bool
(VersionIntervals -> VersionIntervals -> Bool)
-> (VersionIntervals -> VersionIntervals -> Bool)
-> Eq VersionIntervals
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VersionIntervals -> VersionIntervals -> Bool
$c/= :: VersionIntervals -> VersionIntervals -> Bool
== :: VersionIntervals -> VersionIntervals -> Bool
$c== :: VersionIntervals -> VersionIntervals -> Bool
Eq, Int -> VersionIntervals -> ShowS
[VersionIntervals] -> ShowS
VersionIntervals -> String
(Int -> VersionIntervals -> ShowS)
-> (VersionIntervals -> String)
-> ([VersionIntervals] -> ShowS)
-> Show VersionIntervals
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VersionIntervals] -> ShowS
$cshowList :: [VersionIntervals] -> ShowS
show :: VersionIntervals -> String
$cshow :: VersionIntervals -> String
showsPrec :: Int -> VersionIntervals -> ShowS
$cshowsPrec :: Int -> VersionIntervals -> ShowS
Show, Typeable)
unVersionIntervals :: VersionIntervals -> [VersionInterval]
unVersionIntervals :: VersionIntervals -> [VersionInterval]
unVersionIntervals (VersionIntervals [VersionInterval]
is) = [VersionInterval]
is
data VersionInterval = VersionInterval !LowerBound !UpperBound deriving (VersionInterval -> VersionInterval -> Bool
(VersionInterval -> VersionInterval -> Bool)
-> (VersionInterval -> VersionInterval -> Bool)
-> Eq VersionInterval
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VersionInterval -> VersionInterval -> Bool
$c/= :: VersionInterval -> VersionInterval -> Bool
== :: VersionInterval -> VersionInterval -> Bool
$c== :: VersionInterval -> VersionInterval -> Bool
Eq, Int -> VersionInterval -> ShowS
[VersionInterval] -> ShowS
VersionInterval -> String
(Int -> VersionInterval -> ShowS)
-> (VersionInterval -> String)
-> ([VersionInterval] -> ShowS)
-> Show VersionInterval
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VersionInterval] -> ShowS
$cshowList :: [VersionInterval] -> ShowS
show :: VersionInterval -> String
$cshow :: VersionInterval -> String
showsPrec :: Int -> VersionInterval -> ShowS
$cshowsPrec :: Int -> VersionInterval -> ShowS
Show)
data LowerBound = LowerBound !Version !Bound deriving (LowerBound -> LowerBound -> Bool
(LowerBound -> LowerBound -> Bool)
-> (LowerBound -> LowerBound -> Bool) -> Eq LowerBound
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LowerBound -> LowerBound -> Bool
$c/= :: LowerBound -> LowerBound -> Bool
== :: LowerBound -> LowerBound -> Bool
$c== :: LowerBound -> LowerBound -> Bool
Eq, Int -> LowerBound -> ShowS
[LowerBound] -> ShowS
LowerBound -> String
(Int -> LowerBound -> ShowS)
-> (LowerBound -> String)
-> ([LowerBound] -> ShowS)
-> Show LowerBound
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LowerBound] -> ShowS
$cshowList :: [LowerBound] -> ShowS
show :: LowerBound -> String
$cshow :: LowerBound -> String
showsPrec :: Int -> LowerBound -> ShowS
$cshowsPrec :: Int -> LowerBound -> ShowS
Show)
data UpperBound = NoUpperBound | UpperBound !Version !Bound deriving (UpperBound -> UpperBound -> Bool
(UpperBound -> UpperBound -> Bool)
-> (UpperBound -> UpperBound -> Bool) -> Eq UpperBound
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UpperBound -> UpperBound -> Bool
$c/= :: UpperBound -> UpperBound -> Bool
== :: UpperBound -> UpperBound -> Bool
$c== :: UpperBound -> UpperBound -> Bool
Eq, Int -> UpperBound -> ShowS
[UpperBound] -> ShowS
UpperBound -> String
(Int -> UpperBound -> ShowS)
-> (UpperBound -> String)
-> ([UpperBound] -> ShowS)
-> Show UpperBound
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UpperBound] -> ShowS
$cshowList :: [UpperBound] -> ShowS
show :: UpperBound -> String
$cshow :: UpperBound -> String
showsPrec :: Int -> UpperBound -> ShowS
$cshowsPrec :: Int -> UpperBound -> ShowS
Show)
data Bound = ExclusiveBound | InclusiveBound deriving (Bound -> Bound -> Bool
(Bound -> Bound -> Bool) -> (Bound -> Bound -> Bool) -> Eq Bound
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Bound -> Bound -> Bool
$c/= :: Bound -> Bound -> Bool
== :: Bound -> Bound -> Bool
$c== :: Bound -> Bound -> Bool
Eq, Int -> Bound -> ShowS
[Bound] -> ShowS
Bound -> String
(Int -> Bound -> ShowS)
-> (Bound -> String) -> ([Bound] -> ShowS) -> Show Bound
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Bound] -> ShowS
$cshowList :: [Bound] -> ShowS
show :: Bound -> String
$cshow :: Bound -> String
showsPrec :: Int -> Bound -> ShowS
$cshowsPrec :: Int -> Bound -> ShowS
Show)
zeroLowerBound :: LowerBound
zeroLowerBound :: LowerBound
zeroLowerBound = Version -> Bound -> LowerBound
LowerBound Version
version0 Bound
InclusiveBound
isVersion0 :: Version -> Bool
isVersion0 :: Version -> Bool
isVersion0 = Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
(==) Version
version0
stage1 :: VersionRange -> [VersionInterval]
stage1 :: VersionRange -> [VersionInterval]
stage1 = (VersionRangeF [VersionInterval] -> [VersionInterval])
-> VersionRange -> [VersionInterval]
forall a. (VersionRangeF a -> a) -> VersionRange -> a
cataVersionRange VersionRangeF [VersionInterval] -> [VersionInterval]
alg where
alg :: VersionRangeF [VersionInterval] -> [VersionInterval]
alg (ThisVersionF Version
v) = [LowerBound -> UpperBound -> VersionInterval
VersionInterval (Version -> Bound -> LowerBound
LowerBound Version
v Bound
InclusiveBound) (Version -> Bound -> UpperBound
UpperBound Version
v Bound
InclusiveBound)]
alg (LaterVersionF Version
v) = [LowerBound -> UpperBound -> VersionInterval
VersionInterval (Version -> Bound -> LowerBound
LowerBound Version
v Bound
ExclusiveBound) UpperBound
NoUpperBound]
alg (OrLaterVersionF Version
v) = [LowerBound -> UpperBound -> VersionInterval
VersionInterval (Version -> Bound -> LowerBound
LowerBound Version
v Bound
InclusiveBound) UpperBound
NoUpperBound]
alg (EarlierVersionF Version
v)
| Version -> Bool
isVersion0 Version
v = []
| Bool
otherwise = [LowerBound -> UpperBound -> VersionInterval
VersionInterval LowerBound
zeroLowerBound (Version -> Bound -> UpperBound
UpperBound Version
v Bound
ExclusiveBound)]
alg (OrEarlierVersionF Version
v) = [LowerBound -> UpperBound -> VersionInterval
VersionInterval LowerBound
zeroLowerBound (Version -> Bound -> UpperBound
UpperBound Version
v Bound
InclusiveBound)]
alg (MajorBoundVersionF Version
v) = [LowerBound -> UpperBound -> VersionInterval
VersionInterval (Version -> Bound -> LowerBound
LowerBound Version
v Bound
InclusiveBound) (Version -> Bound -> UpperBound
UpperBound (Version -> Version
majorUpperBound Version
v) Bound
ExclusiveBound)]
alg (UnionVersionRangesF [VersionInterval]
v1 [VersionInterval]
v2) = [VersionInterval]
v1 [VersionInterval] -> [VersionInterval] -> [VersionInterval]
forall a. [a] -> [a] -> [a]
++ [VersionInterval]
v2
alg (IntersectVersionRangesF [VersionInterval]
v1 [VersionInterval]
v2) = (VersionInterval -> Maybe VersionInterval)
-> [VersionInterval] -> [VersionInterval]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe VersionInterval -> Maybe VersionInterval
nonEmptyInterval ([VersionInterval] -> [VersionInterval])
-> [VersionInterval] -> [VersionInterval]
forall a b. (a -> b) -> a -> b
$ (VersionInterval -> VersionInterval -> VersionInterval)
-> [VersionInterval] -> [VersionInterval] -> [VersionInterval]
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 VersionInterval -> VersionInterval -> VersionInterval
intersectInterval ([VersionInterval] -> [VersionInterval]
stage2and3 [VersionInterval]
v1) ([VersionInterval] -> [VersionInterval]
stage2and3 [VersionInterval]
v2)
nonEmptyInterval :: VersionInterval -> Maybe VersionInterval
nonEmptyInterval :: VersionInterval -> Maybe VersionInterval
nonEmptyInterval VersionInterval
i | VersionInterval -> Bool
nonEmptyVI VersionInterval
i = VersionInterval -> Maybe VersionInterval
forall a. a -> Maybe a
Just VersionInterval
i
nonEmptyInterval VersionInterval
_ = Maybe VersionInterval
forall a. Maybe a
Nothing
stage2 :: [VersionInterval] -> [VersionInterval]
stage2 :: [VersionInterval] -> [VersionInterval]
stage2 = (VersionInterval -> VersionInterval -> Ordering)
-> [VersionInterval] -> [VersionInterval]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy VersionInterval -> VersionInterval -> Ordering
lowerboundCmp
lowerboundCmp :: VersionInterval -> VersionInterval -> Ordering
lowerboundCmp :: VersionInterval -> VersionInterval -> Ordering
lowerboundCmp (VersionInterval (LowerBound Version
v Bound
vb) UpperBound
_) (VersionInterval (LowerBound Version
u Bound
ub) UpperBound
_) =
Version -> Version -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Version
v Version
u Ordering -> Ordering -> Ordering
forall a. Monoid a => a -> a -> a
`mappend` Bound -> Bound -> Ordering
compareBound Bound
vb Bound
ub
where
compareBound :: Bound -> Bound -> Ordering
compareBound :: Bound -> Bound -> Ordering
compareBound Bound
InclusiveBound Bound
InclusiveBound = Ordering
EQ
compareBound Bound
InclusiveBound Bound
ExclusiveBound = Ordering
LT
compareBound Bound
ExclusiveBound Bound
InclusiveBound = Ordering
GT
compareBound Bound
ExclusiveBound Bound
ExclusiveBound = Ordering
EQ
postprocess :: [VersionInterval] -> VersionIntervals
postprocess :: [VersionInterval] -> VersionIntervals
postprocess = VersionIntervals -> VersionIntervals
checkInvariant (VersionIntervals -> VersionIntervals)
-> ([VersionInterval] -> VersionIntervals)
-> [VersionInterval]
-> VersionIntervals
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [VersionInterval] -> VersionIntervals
VersionIntervals ([VersionInterval] -> VersionIntervals)
-> ([VersionInterval] -> [VersionInterval])
-> [VersionInterval]
-> VersionIntervals
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [VersionInterval] -> [VersionInterval]
stage2and3
stage2and3 :: [VersionInterval] -> [VersionInterval]
stage2and3 :: [VersionInterval] -> [VersionInterval]
stage2and3 = [VersionInterval] -> [VersionInterval]
stage3 ([VersionInterval] -> [VersionInterval])
-> ([VersionInterval] -> [VersionInterval])
-> [VersionInterval]
-> [VersionInterval]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [VersionInterval] -> [VersionInterval]
stage2
stage3 :: [VersionInterval] -> [VersionInterval]
stage3 :: [VersionInterval] -> [VersionInterval]
stage3 [] = []
stage3 (VersionInterval LowerBound
lb UpperBound
ub : [VersionInterval]
rest) = LowerBound -> UpperBound -> [VersionInterval] -> [VersionInterval]
stage3go LowerBound
lb UpperBound
ub [VersionInterval]
rest
stage3go :: LowerBound -> UpperBound -> [VersionInterval] -> [VersionInterval]
stage3go :: LowerBound -> UpperBound -> [VersionInterval] -> [VersionInterval]
stage3go !LowerBound
lb UpperBound
NoUpperBound [VersionInterval]
_ = [LowerBound -> UpperBound -> VersionInterval
VersionInterval LowerBound
lb UpperBound
NoUpperBound]
stage3go !LowerBound
lb !UpperBound
ub [] = [LowerBound -> UpperBound -> VersionInterval
VersionInterval LowerBound
lb UpperBound
ub]
stage3go !LowerBound
lb !UpperBound
ub (VersionInterval LowerBound
lb' UpperBound
ub' : [VersionInterval]
rest')
| UpperBound -> LowerBound -> Bool
doesNotTouch UpperBound
ub LowerBound
lb' = LowerBound -> UpperBound -> VersionInterval
VersionInterval LowerBound
lb UpperBound
ub VersionInterval -> [VersionInterval] -> [VersionInterval]
forall a. a -> [a] -> [a]
: LowerBound -> UpperBound -> [VersionInterval] -> [VersionInterval]
stage3go LowerBound
lb' UpperBound
ub' [VersionInterval]
rest'
| Bool
otherwise = LowerBound -> UpperBound -> [VersionInterval] -> [VersionInterval]
stage3go LowerBound
lb (UpperBound -> UpperBound -> UpperBound
unionUpper UpperBound
ub UpperBound
ub') [VersionInterval]
rest'
intersectInterval :: VersionInterval -> VersionInterval -> VersionInterval
intersectInterval :: VersionInterval -> VersionInterval -> VersionInterval
intersectInterval (VersionInterval LowerBound
lv UpperBound
uv) (VersionInterval LowerBound
lu UpperBound
uu) =
LowerBound -> UpperBound -> VersionInterval
VersionInterval (LowerBound -> LowerBound -> LowerBound
intersectLower LowerBound
lv LowerBound
lu) (UpperBound -> UpperBound -> UpperBound
intersectUpper UpperBound
uv UpperBound
uu)
intersectLower :: LowerBound -> LowerBound -> LowerBound
intersectLower :: LowerBound -> LowerBound -> LowerBound
intersectLower (LowerBound Version
v Bound
vb) (LowerBound Version
u Bound
ub) = case Version -> Version -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Version
v Version
u of
Ordering
EQ -> Version -> Bound -> LowerBound
LowerBound Version
v (Bound -> Bound -> Bound
intersectBound Bound
vb Bound
ub)
Ordering
LT -> Version -> Bound -> LowerBound
LowerBound Version
u Bound
ub
Ordering
GT -> Version -> Bound -> LowerBound
LowerBound Version
v Bound
vb
intersectUpper :: UpperBound -> UpperBound -> UpperBound
intersectUpper :: UpperBound -> UpperBound -> UpperBound
intersectUpper UpperBound
NoUpperBound UpperBound
b = UpperBound
b
intersectUpper UpperBound
b UpperBound
NoUpperBound = UpperBound
b
intersectUpper (UpperBound Version
v Bound
vb) (UpperBound Version
u Bound
ub) = case Version -> Version -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Version
v Version
u of
Ordering
EQ -> Version -> Bound -> UpperBound
UpperBound Version
v (Bound -> Bound -> Bound
intersectBound Bound
vb Bound
ub)
Ordering
LT -> Version -> Bound -> UpperBound
UpperBound Version
v Bound
vb
Ordering
GT -> Version -> Bound -> UpperBound
UpperBound Version
u Bound
ub
intersectBound :: Bound -> Bound -> Bound
intersectBound :: Bound -> Bound -> Bound
intersectBound Bound
InclusiveBound Bound
InclusiveBound = Bound
InclusiveBound
intersectBound Bound
_ Bound
_ = Bound
ExclusiveBound
unionUpper :: UpperBound -> UpperBound -> UpperBound
unionUpper :: UpperBound -> UpperBound -> UpperBound
unionUpper UpperBound
NoUpperBound UpperBound
_ = UpperBound
NoUpperBound
unionUpper UpperBound
_ UpperBound
NoUpperBound = UpperBound
NoUpperBound
unionUpper (UpperBound Version
v Bound
vb) (UpperBound Version
u Bound
ub) = case Version -> Version -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Version
v Version
u of
Ordering
EQ -> Version -> Bound -> UpperBound
UpperBound Version
v (Bound -> Bound -> Bound
unionBound Bound
vb Bound
ub)
Ordering
LT -> Version -> Bound -> UpperBound
UpperBound Version
u Bound
ub
Ordering
GT -> Version -> Bound -> UpperBound
UpperBound Version
v Bound
vb
unionBound :: Bound -> Bound -> Bound
unionBound :: Bound -> Bound -> Bound
unionBound Bound
ExclusiveBound Bound
ExclusiveBound = Bound
ExclusiveBound
unionBound Bound
_ Bound
_ = Bound
InclusiveBound
asVersionIntervals :: VersionRange -> [VersionInterval]
asVersionIntervals :: VersionRange -> [VersionInterval]
asVersionIntervals = VersionIntervals -> [VersionInterval]
unVersionIntervals (VersionIntervals -> [VersionInterval])
-> (VersionRange -> VersionIntervals)
-> VersionRange
-> [VersionInterval]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionRange -> VersionIntervals
toVersionIntervals
doesNotTouch :: UpperBound -> LowerBound -> Bool
doesNotTouch :: UpperBound -> LowerBound -> Bool
doesNotTouch UpperBound
NoUpperBound LowerBound
_ = Bool
False
doesNotTouch (UpperBound Version
u Bound
ub) (LowerBound Version
l Bound
lb) =
(Version
u Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
< Version
l) Bool -> Bool -> Bool
|| (Version
u Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
== Version
l Bool -> Bool -> Bool
&& Bound
ub Bound -> Bound -> Bool
forall a. Eq a => a -> a -> Bool
== Bound
ExclusiveBound Bool -> Bool -> Bool
&& Bound
lb Bound -> Bound -> Bool
forall a. Eq a => a -> a -> Bool
== Bound
ExclusiveBound)
invariantVersionIntervals :: VersionIntervals -> Bool
invariantVersionIntervals :: VersionIntervals -> Bool
invariantVersionIntervals (VersionIntervals [VersionInterval]
intervals) =
(VersionInterval -> Bool) -> [VersionInterval] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all VersionInterval -> Bool
validInterval [VersionInterval]
intervals Bool -> Bool -> Bool
&&
((VersionInterval, VersionInterval) -> Bool)
-> [(VersionInterval, VersionInterval)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (VersionInterval, VersionInterval) -> Bool
doesNotTouch' [(VersionInterval, VersionInterval)]
adjacentIntervals
where
doesNotTouch' :: (VersionInterval, VersionInterval) -> Bool
doesNotTouch' :: (VersionInterval, VersionInterval) -> Bool
doesNotTouch' (VersionInterval LowerBound
_ UpperBound
u, VersionInterval LowerBound
l' UpperBound
_) = UpperBound -> LowerBound -> Bool
doesNotTouch UpperBound
u LowerBound
l'
adjacentIntervals :: [(VersionInterval, VersionInterval)]
adjacentIntervals :: [(VersionInterval, VersionInterval)]
adjacentIntervals = case [VersionInterval]
intervals of
[] -> []
(VersionInterval
_:[VersionInterval]
tl) -> [VersionInterval]
-> [VersionInterval] -> [(VersionInterval, VersionInterval)]
forall a b. [a] -> [b] -> [(a, b)]
zip [VersionInterval]
intervals [VersionInterval]
tl
checkInvariant :: VersionIntervals -> VersionIntervals
checkInvariant :: VersionIntervals -> VersionIntervals
checkInvariant VersionIntervals
is = Bool -> VersionIntervals -> VersionIntervals
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (VersionIntervals -> Bool
invariantVersionIntervals VersionIntervals
is) VersionIntervals
is
{-# INLINE checkInvariant #-}
validInterval :: VersionInterval -> Bool
validInterval :: VersionInterval -> Bool
validInterval i :: VersionInterval
i@(VersionInterval LowerBound
l UpperBound
u) = LowerBound -> Bool
validLower LowerBound
l Bool -> Bool -> Bool
&& UpperBound -> Bool
validUpper UpperBound
u Bool -> Bool -> Bool
&& VersionInterval -> Bool
nonEmptyVI VersionInterval
i
where
validLower :: LowerBound -> Bool
validLower (LowerBound Version
v Bound
_) = Version -> Bool
validVersion Version
v
validUpper :: UpperBound -> Bool
validUpper UpperBound
NoUpperBound = Bool
True
validUpper (UpperBound Version
v Bound
_) = Version -> Bool
validVersion Version
v
nonEmptyVI :: VersionInterval -> Bool
nonEmptyVI :: VersionInterval -> Bool
nonEmptyVI (VersionInterval LowerBound
_ UpperBound
NoUpperBound) = Bool
True
nonEmptyVI (VersionInterval (LowerBound Version
l Bound
lb) (UpperBound Version
u Bound
ub)) =
(Version
l Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
< Version
u) Bool -> Bool -> Bool
|| (Version
l Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
== Version
u Bool -> Bool -> Bool
&& Bound
lb Bound -> Bound -> Bool
forall a. Eq a => a -> a -> Bool
== Bound
InclusiveBound Bool -> Bool -> Bool
&& Bound
ub Bound -> Bound -> Bool
forall a. Eq a => a -> a -> Bool
== Bound
InclusiveBound)
toVersionIntervals :: VersionRange -> VersionIntervals
toVersionIntervals :: VersionRange -> VersionIntervals
toVersionIntervals = [VersionInterval] -> VersionIntervals
postprocess ([VersionInterval] -> VersionIntervals)
-> (VersionRange -> [VersionInterval])
-> VersionRange
-> VersionIntervals
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionRange -> [VersionInterval]
stage1
fromVersionIntervals :: VersionIntervals -> VersionRange
fromVersionIntervals :: VersionIntervals -> VersionRange
fromVersionIntervals (VersionIntervals []) = VersionRange
noVersion
fromVersionIntervals (VersionIntervals (VersionInterval
x:[VersionInterval]
xs)) = (VersionRange -> VersionRange -> VersionRange)
-> NonEmpty VersionRange -> VersionRange
forall a. (a -> a -> a) -> NonEmpty a -> a
foldr1 VersionRange -> VersionRange -> VersionRange
unionVersionRanges ((VersionInterval -> VersionRange)
-> NonEmpty VersionInterval -> NonEmpty VersionRange
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VersionInterval -> VersionRange
intervalToVersionRange (VersionInterval
xVersionInterval -> [VersionInterval] -> NonEmpty VersionInterval
forall a. a -> [a] -> NonEmpty a
:|[VersionInterval]
xs))
intervalToVersionRange :: VersionInterval -> VersionRange
intervalToVersionRange :: VersionInterval -> VersionRange
intervalToVersionRange (VersionInterval (LowerBound Version
v Bound
vb) UpperBound
upper') = case UpperBound
upper' of
UpperBound
NoUpperBound
-> VersionRange
lowerBound
UpperBound Version
u Bound
ub
| Bound
vb Bound -> Bound -> Bool
forall a. Eq a => a -> a -> Bool
== Bound
InclusiveBound
, Bound
ub Bound -> Bound -> Bool
forall a. Eq a => a -> a -> Bool
== Bound
InclusiveBound
, Version
v Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
== Version
u
-> Version -> VersionRange
thisVersion Version
v
UpperBound Version
u Bound
ub -> VersionRange -> VersionRange
withLowerBound (Version -> Bound -> VersionRange
makeUpperBound Version
u Bound
ub)
where
lowerBound :: VersionRange
lowerBound :: VersionRange
lowerBound = case Bound
vb of
Bound
InclusiveBound -> Version -> VersionRange
orLaterVersion Version
v
Bound
ExclusiveBound -> Version -> VersionRange
laterVersion Version
v
withLowerBound :: VersionRange -> VersionRange
withLowerBound :: VersionRange -> VersionRange
withLowerBound VersionRange
vr
| Version -> Bool
isVersion0 Version
v, Bound
vb Bound -> Bound -> Bool
forall a. Eq a => a -> a -> Bool
== Bound
InclusiveBound = VersionRange
vr
| Bool
otherwise = VersionRange -> VersionRange -> VersionRange
intersectVersionRanges VersionRange
lowerBound VersionRange
vr
makeUpperBound :: Version -> Bound -> VersionRange
makeUpperBound :: Version -> Bound -> VersionRange
makeUpperBound Version
u Bound
InclusiveBound = Version -> VersionRange
orEarlierVersion Version
u
makeUpperBound Version
u Bound
ExclusiveBound = Version -> VersionRange
earlierVersion Version
u
normaliseVersionRange2 :: VersionRange -> VersionRange
normaliseVersionRange2 :: VersionRange -> VersionRange
normaliseVersionRange2 = VersionIntervals -> VersionRange
fromVersionIntervals (VersionIntervals -> VersionRange)
-> (VersionRange -> VersionIntervals)
-> VersionRange
-> VersionRange
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionRange -> VersionIntervals
toVersionIntervals
relaxLastInterval :: VersionIntervals -> VersionIntervals
relaxLastInterval :: VersionIntervals -> VersionIntervals
relaxLastInterval (VersionIntervals [VersionInterval]
xs) = [VersionInterval] -> VersionIntervals
VersionIntervals ([VersionInterval] -> [VersionInterval]
relaxLastInterval' [VersionInterval]
xs)
where
relaxLastInterval' :: [VersionInterval] -> [VersionInterval]
relaxLastInterval' [] = []
relaxLastInterval' [VersionInterval LowerBound
l UpperBound
_] = [LowerBound -> UpperBound -> VersionInterval
VersionInterval LowerBound
l UpperBound
NoUpperBound]
relaxLastInterval' (VersionInterval
i:[VersionInterval]
is) = VersionInterval
i VersionInterval -> [VersionInterval] -> [VersionInterval]
forall a. a -> [a] -> [a]
: [VersionInterval] -> [VersionInterval]
relaxLastInterval' [VersionInterval]
is
relaxHeadInterval :: VersionIntervals -> VersionIntervals
relaxHeadInterval :: VersionIntervals -> VersionIntervals
relaxHeadInterval (VersionIntervals [VersionInterval]
xs) = [VersionInterval] -> VersionIntervals
VersionIntervals ([VersionInterval] -> [VersionInterval]
relaxHeadInterval' [VersionInterval]
xs)
where
relaxHeadInterval' :: [VersionInterval] -> [VersionInterval]
relaxHeadInterval' [] = []
relaxHeadInterval' (VersionInterval LowerBound
_ UpperBound
u : [VersionInterval]
is) = LowerBound -> UpperBound -> VersionInterval
VersionInterval LowerBound
zeroLowerBound UpperBound
u VersionInterval -> [VersionInterval] -> [VersionInterval]
forall a. a -> [a] -> [a]
: [VersionInterval]
is