{-# OPTIONS_GHC -Wall #-} module Distribution.Version.Invert ( invertVersionRange , invertVersionIntervals ) where import Distribution.Version (Version(Version, versionBranch, versionTags), VersionRange, fromVersionIntervals, asVersionIntervals, mkVersionIntervals, LowerBound(LowerBound), UpperBound(UpperBound, NoUpperBound), Bound(InclusiveBound, ExclusiveBound)) -- | This function belongs in Cabal, see http://hackage.haskell.org/trac/hackage/ticket/935. invertVersionRange :: VersionRange -> VersionRange invertVersionRange = fromVersionIntervals . maybe (error "invertVersionRange") id . mkVersionIntervals . invertVersionIntervals . asVersionIntervals invertVersionIntervals :: [(LowerBound, UpperBound)] -> [(LowerBound, UpperBound)] invertVersionIntervals xs = case xs of [] -> [(lb0, NoUpperBound)] ((LowerBound (Version {versionBranch = [0], versionTags = []}) InclusiveBound, ub) : more) -> invertVersionIntervals' ub more ((lb, ub) : more) -> (lb0, invertLowerBound lb) : invertVersionIntervals' ub more where invertVersionIntervals' :: UpperBound -> [(LowerBound, UpperBound)] -> [(LowerBound, UpperBound)] invertVersionIntervals' NoUpperBound [] = [] invertVersionIntervals' ub0 [] = [(invertUpperBound ub0, NoUpperBound)] invertVersionIntervals' ub0 [(lb, NoUpperBound)] = [(invertUpperBound ub0, invertLowerBound lb)] invertVersionIntervals' ub0 ((lb, ub1) : more) = (invertUpperBound ub0, invertLowerBound lb) : invertVersionIntervals' ub1 more invertLowerBound :: LowerBound -> UpperBound invertLowerBound (LowerBound v b) = UpperBound v (invertBound b) invertUpperBound :: UpperBound -> LowerBound invertUpperBound (UpperBound v b) = LowerBound v (invertBound b) invertUpperBound NoUpperBound = error "NoUpperBound: unexpected" invertBound :: Bound -> Bound invertBound ExclusiveBound = InclusiveBound invertBound InclusiveBound = ExclusiveBound lb0 :: LowerBound lb0 = LowerBound (Version {versionBranch = [0], versionTags = []}) InclusiveBound