hix-0.7.0: lib/Hix/Managed/Diff.hs
module Hix.Managed.Diff where
import Hix.Class.Map (NMap, nAmend, nMap)
import Hix.Data.Version (Version)
import qualified Hix.Data.VersionBounds
import Hix.Data.VersionBounds (anyBounds, VersionBounds)
import Hix.Managed.Data.Diff (BoundsChange, BoundsDiffDetail (..), Change (..), Diff (..), VersionChange)
import Hix.Managed.Data.Mutable (MutableBounds, MutableDep, MutableDeps, MutableVersions)
import Hix.These (maybeThese)
diffOriginal :: Diff d a -> Maybe a
diffOriginal = \case
DiffChanged original _ _ -> Just original
_ -> Nothing
changeOriginal :: Change d a -> Maybe a
changeOriginal = \case
Unchanged original -> original
Changed d -> diffOriginal d
reifyChangeWith :: b -> (a -> b) -> Change d a -> b
reifyChangeWith absent f = \case
Unchanged Nothing -> absent
Unchanged (Just a) -> f a
Changed (DiffAdded a) -> f a
Changed (DiffChanged _ a _) -> f a
reifyChange :: a -> Change d a -> a
reifyChange absent = reifyChangeWith absent id
reifyChangeMaybe :: Change d a -> Maybe a
reifyChangeMaybe = reifyChangeWith Nothing Just
reifyBoundsChangeMaybe :: BoundsChange -> Maybe VersionBounds
reifyBoundsChangeMaybe = reifyChangeMaybe
reifyBoundsChange :: BoundsChange -> VersionBounds
reifyBoundsChange = reifyChange anyBounds
reifyBoundsChanges :: MutableDeps BoundsChange -> MutableBounds
reifyBoundsChanges = nMap reifyBoundsChange
reifyVersionChange :: VersionChange -> Maybe Version
reifyVersionChange = reifyChangeMaybe
reifyVersionChanges :: MutableDeps VersionChange -> MutableVersions
reifyVersionChanges = nMap reifyVersionChange
applyVersionChange :: VersionChange -> Maybe Version -> Maybe Version
applyVersionChange d _ = reifyVersionChange d
applyBoundsChange :: BoundsChange -> VersionBounds -> VersionBounds
applyBoundsChange d old =
fromMaybe old (reifyBoundsChangeMaybe d)
diff ::
(a -> a -> Maybe d) ->
a ->
a ->
Change d a
diff mkDetail original new =
case mkDetail original new of
Just detail -> Changed (DiffChanged original new detail)
Nothing -> Unchanged (Just original)
diffMaybe ::
(a -> a -> Maybe d) ->
Maybe a ->
Maybe a ->
Change d a
diffMaybe mkDetail original new =
case (original, new) of
(Just o, Just n) -> diff mkDetail o n
(Just o, Nothing) -> Unchanged (Just o)
(Nothing, Just n) -> Changed (DiffAdded n)
(Nothing, Nothing) -> Unchanged Nothing
versionDiffDetail :: Version -> Version -> Maybe ()
versionDiffDetail original new
| original == new
= Nothing
| otherwise
= Just ()
versionChange :: Maybe Version -> Maybe Version -> VersionChange
versionChange = diffMaybe versionDiffDetail
versionDiff :: Maybe Version -> Maybe Version -> Maybe (Diff () Version)
versionDiff original new =
case versionChange original new of
Changed d -> Just d
Unchanged _ -> Nothing
boundsDiffDetail :: VersionBounds -> VersionBounds -> Maybe BoundsDiffDetail
boundsDiffDetail original new =
BoundsDiffDetail <$> maybeThese diffL diffU
where
diffL = versionDiff original.lower combined.lower
diffU = versionDiff original.upper combined.upper
combined = new <> original
boundsChange :: VersionBounds -> VersionBounds -> BoundsChange
boundsChange = diff boundsDiffDetail
updateVersionChange :: Version -> VersionChange -> VersionChange
updateVersionChange new d =
diffMaybe versionDiffDetail (changeOriginal d) (Just new)
-- | We never want to remove any bounds, but mutations only return the bound they have targeted, so we need to fall back
-- to the original bounds when updating.
updateBoundsChange :: VersionBounds -> BoundsChange -> BoundsChange
updateBoundsChange new d =
diffMaybe boundsDiffDetail original (Just combined)
where
(original, combined) = case changeOriginal d of
Just o -> (Just o, new <> o)
Nothing -> (Nothing, new)
updateVersionChanges ::
NMap vmap MutableDep (Maybe Version) s1 =>
NMap map MutableDep VersionChange s2 =>
vmap ->
map ->
map
updateVersionChanges =
nAmend (maybe id updateVersionChange)
updateBoundsChanges ::
NMap vmap MutableDep VersionBounds s1 =>
NMap map MutableDep BoundsChange s2 =>
vmap ->
map ->
map
updateBoundsChanges =
nAmend updateBoundsChange
initChanges ::
NMap map1 k (Maybe v1) s1 =>
NMap map2 k (Change d v1) s2 =>
map1 ->
map2
initChanges =
nMap Unchanged