{-# LANGUAGE DeriveFunctor       #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE DerivingStrategies  #-}
{-# LANGUAGE DerivingVia         #-}
{-# LANGUAGE RankNTypes          #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving  #-}
{-# LANGUAGE StaticPointers      #-}

module Ouroboros.Network.ConnectionId where

import NoThunks.Class (InspectHeap (..), NoThunks)

import Data.Hashable
import GHC.Generics (Generic)
import Ouroboros.Network.Util.ShowProxy (Proxy (..), ShowProxy (..))


-- | Connection is identified by local and remote address.
--
-- TODO: the type variable which this data type fills in is called `peerid`.  We
-- should renamed to `connectionId`.
--
data ConnectionId addr = ConnectionId {
    forall addr. ConnectionId addr -> addr
localAddress  :: !addr,
    forall addr. ConnectionId addr -> addr
remoteAddress :: !addr
  }
  deriving (ConnectionId addr -> ConnectionId addr -> Bool
(ConnectionId addr -> ConnectionId addr -> Bool)
-> (ConnectionId addr -> ConnectionId addr -> Bool)
-> Eq (ConnectionId addr)
forall addr.
Eq addr =>
ConnectionId addr -> ConnectionId addr -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall addr.
Eq addr =>
ConnectionId addr -> ConnectionId addr -> Bool
== :: ConnectionId addr -> ConnectionId addr -> Bool
$c/= :: forall addr.
Eq addr =>
ConnectionId addr -> ConnectionId addr -> Bool
/= :: ConnectionId addr -> ConnectionId addr -> Bool
Eq, Int -> ConnectionId addr -> ShowS
[ConnectionId addr] -> ShowS
ConnectionId addr -> String
(Int -> ConnectionId addr -> ShowS)
-> (ConnectionId addr -> String)
-> ([ConnectionId addr] -> ShowS)
-> Show (ConnectionId addr)
forall addr. Show addr => Int -> ConnectionId addr -> ShowS
forall addr. Show addr => [ConnectionId addr] -> ShowS
forall addr. Show addr => ConnectionId addr -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall addr. Show addr => Int -> ConnectionId addr -> ShowS
showsPrec :: Int -> ConnectionId addr -> ShowS
$cshow :: forall addr. Show addr => ConnectionId addr -> String
show :: ConnectionId addr -> String
$cshowList :: forall addr. Show addr => [ConnectionId addr] -> ShowS
showList :: [ConnectionId addr] -> ShowS
Show, (forall x. ConnectionId addr -> Rep (ConnectionId addr) x)
-> (forall x. Rep (ConnectionId addr) x -> ConnectionId addr)
-> Generic (ConnectionId addr)
forall x. Rep (ConnectionId addr) x -> ConnectionId addr
forall x. ConnectionId addr -> Rep (ConnectionId addr) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall addr x. Rep (ConnectionId addr) x -> ConnectionId addr
forall addr x. ConnectionId addr -> Rep (ConnectionId addr) x
$cfrom :: forall addr x. ConnectionId addr -> Rep (ConnectionId addr) x
from :: forall x. ConnectionId addr -> Rep (ConnectionId addr) x
$cto :: forall addr x. Rep (ConnectionId addr) x -> ConnectionId addr
to :: forall x. Rep (ConnectionId addr) x -> ConnectionId addr
Generic)
  deriving Context -> ConnectionId addr -> IO (Maybe ThunkInfo)
Proxy (ConnectionId addr) -> String
(Context -> ConnectionId addr -> IO (Maybe ThunkInfo))
-> (Context -> ConnectionId addr -> IO (Maybe ThunkInfo))
-> (Proxy (ConnectionId addr) -> String)
-> NoThunks (ConnectionId addr)
forall addr.
Typeable addr =>
Context -> ConnectionId addr -> IO (Maybe ThunkInfo)
forall addr. Typeable addr => Proxy (ConnectionId addr) -> String
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: forall addr.
Typeable addr =>
Context -> ConnectionId addr -> IO (Maybe ThunkInfo)
noThunks :: Context -> ConnectionId addr -> IO (Maybe ThunkInfo)
$cwNoThunks :: forall addr.
Typeable addr =>
Context -> ConnectionId addr -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> ConnectionId addr -> IO (Maybe ThunkInfo)
$cshowTypeOf :: forall addr. Typeable addr => Proxy (ConnectionId addr) -> String
showTypeOf :: Proxy (ConnectionId addr) -> String
NoThunks via InspectHeap (ConnectionId addr)
  deriving (forall a b. (a -> b) -> ConnectionId a -> ConnectionId b)
-> (forall a b. a -> ConnectionId b -> ConnectionId a)
-> Functor ConnectionId
forall a b. a -> ConnectionId b -> ConnectionId a
forall a b. (a -> b) -> ConnectionId a -> ConnectionId b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> ConnectionId a -> ConnectionId b
fmap :: forall a b. (a -> b) -> ConnectionId a -> ConnectionId b
$c<$ :: forall a b. a -> ConnectionId b -> ConnectionId a
<$ :: forall a b. a -> ConnectionId b -> ConnectionId a
Functor

-- | Order first by `remoteAddress` then by `localAddress`.
--
-- /Note:/ we relay on the fact that `remoteAddress` is an order
-- preserving map (which allows us to use `Map.mapKeysMonotonic` in some
-- cases.  We also relay on this particular order in
-- `Ouroboros.Network.ConnectionManager.State.liveConnections`
--
instance Ord addr => Ord (ConnectionId addr) where
    ConnectionId addr
conn compare :: ConnectionId addr -> ConnectionId addr -> Ordering
`compare` ConnectionId addr
conn' =
         ConnectionId addr -> addr
forall addr. ConnectionId addr -> addr
remoteAddress ConnectionId addr
conn addr -> addr -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` ConnectionId addr -> addr
forall addr. ConnectionId addr -> addr
remoteAddress ConnectionId addr
conn'
      Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> ConnectionId addr -> addr
forall addr. ConnectionId addr -> addr
localAddress ConnectionId addr
conn addr -> addr -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` ConnectionId addr -> addr
forall addr. ConnectionId addr -> addr
localAddress ConnectionId addr
conn'

instance Hashable a => Hashable (ConnectionId a)

instance forall addr. ShowProxy addr => ShowProxy (ConnectionId addr) where
  showProxy :: Proxy (ConnectionId addr) -> String
showProxy Proxy (ConnectionId addr)
_ = String
"ConnectionId " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Proxy addr -> String
forall {k} (p :: k). ShowProxy p => Proxy p -> String
showProxy (Proxy addr
forall {k} (t :: k). Proxy t
Proxy :: Proxy addr)