{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Ouroboros.Network.Protocol.Handshake.Version
( Versions (..)
, updateVersionData
, Version (..)
, VersionMismatch (..)
, simpleSingletonVersions
, foldMapVersions
, combineVersions
, Accept (..)
, Acceptable (..)
, Queryable (..)
) where
import Data.Foldable (toList)
import Data.Map (Map)
import Data.Map qualified as Map
import GHC.Stack (HasCallStack)
import Ouroboros.Network.Handshake.Acceptable (Accept (..), Acceptable (..))
import Ouroboros.Network.Handshake.Queryable (Queryable (..))
newtype Versions vNum vData r = Versions
{ forall vNum vData r.
Versions vNum vData r -> Map vNum (Version vData r)
getVersions :: Map vNum (Version vData r)
}
deriving NonEmpty (Versions vNum vData r) -> Versions vNum vData r
Versions vNum vData r
-> Versions vNum vData r -> Versions vNum vData r
(Versions vNum vData r
-> Versions vNum vData r -> Versions vNum vData r)
-> (NonEmpty (Versions vNum vData r) -> Versions vNum vData r)
-> (forall b.
Integral b =>
b -> Versions vNum vData r -> Versions vNum vData r)
-> Semigroup (Versions vNum vData r)
forall b.
Integral b =>
b -> Versions vNum vData r -> Versions vNum vData r
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall vNum vData r.
Ord vNum =>
NonEmpty (Versions vNum vData r) -> Versions vNum vData r
forall vNum vData r.
Ord vNum =>
Versions vNum vData r
-> Versions vNum vData r -> Versions vNum vData r
forall vNum vData r b.
(Ord vNum, Integral b) =>
b -> Versions vNum vData r -> Versions vNum vData r
$c<> :: forall vNum vData r.
Ord vNum =>
Versions vNum vData r
-> Versions vNum vData r -> Versions vNum vData r
<> :: Versions vNum vData r
-> Versions vNum vData r -> Versions vNum vData r
$csconcat :: forall vNum vData r.
Ord vNum =>
NonEmpty (Versions vNum vData r) -> Versions vNum vData r
sconcat :: NonEmpty (Versions vNum vData r) -> Versions vNum vData r
$cstimes :: forall vNum vData r b.
(Ord vNum, Integral b) =>
b -> Versions vNum vData r -> Versions vNum vData r
stimes :: forall b.
Integral b =>
b -> Versions vNum vData r -> Versions vNum vData r
Semigroup
updateVersionData :: (vData -> vData) -> Versions vNum vData r -> Versions vNum vData r
updateVersionData :: forall vData vNum r.
(vData -> vData) -> Versions vNum vData r -> Versions vNum vData r
updateVersionData vData -> vData
fn =
Map vNum (Version vData r) -> Versions vNum vData r
forall vNum vData r.
Map vNum (Version vData r) -> Versions vNum vData r
Versions
(Map vNum (Version vData r) -> Versions vNum vData r)
-> (Versions vNum vData r -> Map vNum (Version vData r))
-> Versions vNum vData r
-> Versions vNum vData r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Version vData r -> Version vData r)
-> Map vNum (Version vData r) -> Map vNum (Version vData r)
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map (\Version vData r
v -> Version vData r
v { versionData = fn (versionData v) })
(Map vNum (Version vData r) -> Map vNum (Version vData r))
-> (Versions vNum vData r -> Map vNum (Version vData r))
-> Versions vNum vData r
-> Map vNum (Version vData r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Versions vNum vData r -> Map vNum (Version vData r)
forall vNum vData r.
Versions vNum vData r -> Map vNum (Version vData r)
getVersions
instance Functor (Versions vNum extra) where
fmap :: forall a b.
(a -> b) -> Versions vNum extra a -> Versions vNum extra b
fmap a -> b
f (Versions Map vNum (Version extra a)
vs) = Map vNum (Version extra b) -> Versions vNum extra b
forall vNum vData r.
Map vNum (Version vData r) -> Versions vNum vData r
Versions (Map vNum (Version extra b) -> Versions vNum extra b)
-> Map vNum (Version extra b) -> Versions vNum extra b
forall a b. (a -> b) -> a -> b
$ (Version extra a -> Version extra b)
-> Map vNum (Version extra a) -> Map vNum (Version extra b)
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map ((a -> b) -> Version extra a -> Version extra b
forall a b. (a -> b) -> Version extra a -> Version extra b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) Map vNum (Version extra a)
vs
foldMapVersions :: (Ord vNum, Foldable f, HasCallStack)
=> (x -> Versions vNum extra r)
-> f x
-> Versions vNum extra r
foldMapVersions :: forall vNum (f :: * -> *) x extra r.
(Ord vNum, Foldable f, HasCallStack) =>
(x -> Versions vNum extra r) -> f x -> Versions vNum extra r
foldMapVersions x -> Versions vNum extra r
f f x
fx = case f x -> [x]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f x
fx of
[] -> [Char] -> Versions vNum extra r
forall a. HasCallStack => [Char] -> a
error [Char]
"foldMapVersions: precondition violated"
[x]
xs -> (Versions vNum extra r
-> Versions vNum extra r -> Versions vNum extra r)
-> [Versions vNum extra r] -> Versions vNum extra r
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 Versions vNum extra r
-> Versions vNum extra r -> Versions vNum extra r
forall a. Semigroup a => a -> a -> a
(<>) ((x -> Versions vNum extra r) -> [x] -> [Versions vNum extra r]
forall a b. (a -> b) -> [a] -> [b]
map x -> Versions vNum extra r
f [x]
xs)
combineVersions :: (Ord vNum, Foldable f, HasCallStack)
=> f (Versions vNum extra r)
-> Versions vNum extra r
combineVersions :: forall vNum (f :: * -> *) extra r.
(Ord vNum, Foldable f, HasCallStack) =>
f (Versions vNum extra r) -> Versions vNum extra r
combineVersions = (Versions vNum extra r -> Versions vNum extra r)
-> f (Versions vNum extra r) -> Versions vNum extra r
forall vNum (f :: * -> *) x extra r.
(Ord vNum, Foldable f, HasCallStack) =>
(x -> Versions vNum extra r) -> f x -> Versions vNum extra r
foldMapVersions Versions vNum extra r -> Versions vNum extra r
forall a. a -> a
id
data Version vData r = Version
{ forall vData r. Version vData r -> vData -> r
versionApplication :: vData -> r
, forall vData r. Version vData r -> vData
versionData :: vData
}
deriving (forall a b. (a -> b) -> Version vData a -> Version vData b)
-> (forall a b. a -> Version vData b -> Version vData a)
-> Functor (Version vData)
forall a b. a -> Version vData b -> Version vData a
forall a b. (a -> b) -> Version vData a -> Version vData b
forall vData a b. a -> Version vData b -> Version vData a
forall vData a b. (a -> b) -> Version vData a -> Version vData b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall vData a b. (a -> b) -> Version vData a -> Version vData b
fmap :: forall a b. (a -> b) -> Version vData a -> Version vData b
$c<$ :: forall vData a b. a -> Version vData b -> Version vData a
<$ :: forall a b. a -> Version vData b -> Version vData a
Functor
data VersionMismatch vNum where
NoCommonVersion :: VersionMismatch vNum
InconsistentVersion :: vNum -> VersionMismatch vNum
simpleSingletonVersions
:: vNum
-> vData
-> r
-> Versions vNum vData r
simpleSingletonVersions :: forall vNum vData r. vNum -> vData -> r -> Versions vNum vData r
simpleSingletonVersions vNum
vNum vData
vData r
r =
Map vNum (Version vData r) -> Versions vNum vData r
forall vNum vData r.
Map vNum (Version vData r) -> Versions vNum vData r
Versions
(Map vNum (Version vData r) -> Versions vNum vData r)
-> Map vNum (Version vData r) -> Versions vNum vData r
forall a b. (a -> b) -> a -> b
$ vNum -> Version vData r -> Map vNum (Version vData r)
forall k a. k -> a -> Map k a
Map.singleton vNum
vNum
((vData -> r) -> vData -> Version vData r
forall vData r. (vData -> r) -> vData -> Version vData r
Version (\vData
_ -> r
r) vData
vData)