{-# options_ghc -Wno-orphans #-}

module Hix.Orphans.Version where

import Distribution.Version (
  LowerBound (LowerBound),
  UpperBound (NoUpperBound, UpperBound),
  Version,
  VersionInterval (VersionInterval),
  VersionRange,
  asVersionIntervals,
  earlierVersion,
  intersectVersionRanges,
  mkVersion,
  orLaterVersion,
  unionVersionRanges,
  version0,
  versionNumbers,
  )
import GHC.Exts (IsList (..))

instance IsList Version where
  type Item Version = Int

  fromList :: [Item Version] -> Version
fromList = [Int] -> Version
[Item Version] -> Version
mkVersion

  toList :: Version -> [Item Version]
toList = Version -> [Int]
Version -> [Item Version]
versionNumbers

instance IsList VersionRange where
  type Item VersionRange = Version

  fromList :: [Item VersionRange] -> VersionRange
fromList = \case
    [] -> Version -> VersionRange
orLaterVersion Version
version0
    [Item [Version]
v] -> Version -> VersionRange
orLaterVersion Version
Item [Version]
v
    [Item [Version]
l, Item [Version]
u] -> Version -> Version -> VersionRange
range Version
Item [Version]
l Version
Item [Version]
u
    Item VersionRange
l : Item VersionRange
u : [Item VersionRange]
rest -> VersionRange -> VersionRange -> VersionRange
unionVersionRanges (Version -> Version -> VersionRange
range Version
Item VersionRange
l Version
Item VersionRange
u) ([Item VersionRange] -> VersionRange
forall l. IsList l => [Item l] -> l
fromList [Item VersionRange]
rest)
    where
      range :: Version -> Version -> VersionRange
range Version
l Version
u = VersionRange -> VersionRange -> VersionRange
intersectVersionRanges (Version -> VersionRange
orLaterVersion Version
l) (Version -> VersionRange
earlierVersion Version
u)

  toList :: VersionRange -> [Item VersionRange]
toList VersionRange
range = do
    VersionInterval (LowerBound Version
v Bound
_) UpperBound
upper <- VersionRange -> [VersionInterval]
asVersionIntervals VersionRange
range
    Version
v Version -> [Version] -> [Version]
forall a. a -> [a] -> [a]
: UpperBound -> [Version]
fromUpper UpperBound
upper
    where
      fromUpper :: UpperBound -> [Version]
fromUpper = \case
        UpperBound
NoUpperBound -> []
        UpperBound Version
v Bound
_ -> [Version
Item [Version]
v]