{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE UndecidableInstances #-}

{- | Description: A specialized channel for outgoing peer messages. -}
module OM.Legion.MsgChan (
  MsgChan,
  Peer(..),
  ClusterName(..),
  MessageId(..),
  PeerMessage(..),
  close,
  enqueueMsg,
  newMsgChan,
  stream,
) where

import Control.Concurrent.STM (TVar, atomically, newTVarIO, readTVar,
  retry, writeTVar)
import Control.Monad (join)
import Control.Monad.IO.Class (MonadIO(liftIO))
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
import Data.Binary (Binary, Word64)
import Data.ByteString.Lazy (ByteString)
import Data.CRDT.EventFold (Event(Output, State), Diff, EventFold,
  EventId)
import Data.Conduit (ConduitT, yield)
import Data.Foldable (traverse_)
import Data.Map (Map)
import Data.String (IsString)
import Data.Text (Text)
import Data.UUID (UUID)
import GHC.Generics (Generic)
import Web.HttpApiData (FromHttpApiData, ToHttpApiData)


{- | A specialized channel for outgoing peer messages.  -}
newtype MsgChan e = MsgChan
  { forall e. MsgChan e -> TVar (Maybe [PeerMessage e])
_unMsgChan :: TVar (Maybe [PeerMessage e])
  }


{- | Create a new 'MsgChan'. -}
newMsgChan :: (MonadIO m) => m (MsgChan e)
newMsgChan :: forall (m :: * -> *) e. MonadIO m => m (MsgChan e)
newMsgChan = IO (MsgChan e) -> m (MsgChan e)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MsgChan e) -> m (MsgChan e))
-> IO (MsgChan e) -> m (MsgChan e)
forall a b. (a -> b) -> a -> b
$ TVar (Maybe [PeerMessage e]) -> MsgChan e
forall e. TVar (Maybe [PeerMessage e]) -> MsgChan e
MsgChan (TVar (Maybe [PeerMessage e]) -> MsgChan e)
-> IO (TVar (Maybe [PeerMessage e])) -> IO (MsgChan e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [PeerMessage e] -> IO (TVar (Maybe [PeerMessage e]))
forall a. a -> IO (TVar a)
newTVarIO ([PeerMessage e] -> Maybe [PeerMessage e]
forall a. a -> Maybe a
Just [])


{- | Close a MsgChan. -}
close :: (MonadIO m) => MsgChan e -> m ()
close :: forall (m :: * -> *) e. MonadIO m => MsgChan e -> m ()
close (MsgChan TVar (Maybe [PeerMessage e])
chan) =
  (IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (STM () -> IO ()) -> STM () -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM () -> IO ()
forall a. STM a -> IO a
atomically) (TVar (Maybe [PeerMessage e]) -> Maybe [PeerMessage e] -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar (Maybe [PeerMessage e])
chan Maybe [PeerMessage e]
forall a. Maybe a
Nothing)


stream
  :: MonadIO m
  => Peer
  -> MsgChan e
  -> ConduitT void (Peer, PeerMessage e) m ()
stream :: forall (m :: * -> *) e void.
MonadIO m =>
Peer -> MsgChan e -> ConduitT void (Peer, PeerMessage e) m ()
stream Peer
self (MsgChan TVar (Maybe [PeerMessage e])
chan) =
  (ConduitT
  void
  (Peer, PeerMessage e)
  m
  (ConduitT void (Peer, PeerMessage e) m ())
-> ConduitT void (Peer, PeerMessage e) m ()
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (ConduitT
   void
   (Peer, PeerMessage e)
   m
   (ConduitT void (Peer, PeerMessage e) m ())
 -> ConduitT void (Peer, PeerMessage e) m ())
-> (STM (ConduitT void (Peer, PeerMessage e) m ())
    -> ConduitT
         void
         (Peer, PeerMessage e)
         m
         (ConduitT void (Peer, PeerMessage e) m ()))
-> STM (ConduitT void (Peer, PeerMessage e) m ())
-> ConduitT void (Peer, PeerMessage e) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (ConduitT void (Peer, PeerMessage e) m ())
-> ConduitT
     void
     (Peer, PeerMessage e)
     m
     (ConduitT void (Peer, PeerMessage e) m ())
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ConduitT void (Peer, PeerMessage e) m ())
 -> ConduitT
      void
      (Peer, PeerMessage e)
      m
      (ConduitT void (Peer, PeerMessage e) m ()))
-> (STM (ConduitT void (Peer, PeerMessage e) m ())
    -> IO (ConduitT void (Peer, PeerMessage e) m ()))
-> STM (ConduitT void (Peer, PeerMessage e) m ())
-> ConduitT
     void
     (Peer, PeerMessage e)
     m
     (ConduitT void (Peer, PeerMessage e) m ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM (ConduitT void (Peer, PeerMessage e) m ())
-> IO (ConduitT void (Peer, PeerMessage e) m ())
forall a. STM a -> IO a
atomically) (STM (ConduitT void (Peer, PeerMessage e) m ())
 -> ConduitT void (Peer, PeerMessage e) m ())
-> STM (ConduitT void (Peer, PeerMessage e) m ())
-> ConduitT void (Peer, PeerMessage e) m ()
forall a b. (a -> b) -> a -> b
$
    TVar (Maybe [PeerMessage e]) -> STM (Maybe [PeerMessage e])
forall a. TVar a -> STM a
readTVar TVar (Maybe [PeerMessage e])
chan STM (Maybe [PeerMessage e])
-> (Maybe [PeerMessage e]
    -> STM (ConduitT void (Peer, PeerMessage e) m ()))
-> STM (ConduitT void (Peer, PeerMessage e) m ())
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Maybe [PeerMessage e]
Nothing ->
        {- The stream is closed, so stop.  -}
        ConduitT void (Peer, PeerMessage e) m ()
-> STM (ConduitT void (Peer, PeerMessage e) m ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (() -> ConduitT void (Peer, PeerMessage e) m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
      Just [] ->
        {- The stream is empty, so wait. -}
        STM (ConduitT void (Peer, PeerMessage e) m ())
forall a. STM a
retry
      Just [PeerMessage e]
messages -> do
        {-
          The stream is not empty, consume the messages and set the
          stream to empty.
        -}
        TVar (Maybe [PeerMessage e]) -> Maybe [PeerMessage e] -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar (Maybe [PeerMessage e])
chan ([PeerMessage e] -> Maybe [PeerMessage e]
forall a. a -> Maybe a
Just []) 
        ConduitT void (Peer, PeerMessage e) m ()
-> STM (ConduitT void (Peer, PeerMessage e) m ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ConduitT void (Peer, PeerMessage e) m ()
 -> STM (ConduitT void (Peer, PeerMessage e) m ()))
-> ConduitT void (Peer, PeerMessage e) m ()
-> STM (ConduitT void (Peer, PeerMessage e) m ())
forall a b. (a -> b) -> a -> b
$ do
          (PeerMessage e -> ConduitT void (Peer, PeerMessage e) m ())
-> [PeerMessage e] -> ConduitT void (Peer, PeerMessage e) m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ ((Peer, PeerMessage e) -> ConduitT void (Peer, PeerMessage e) m ()
forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ((Peer, PeerMessage e) -> ConduitT void (Peer, PeerMessage e) m ())
-> (PeerMessage e -> (Peer, PeerMessage e))
-> PeerMessage e
-> ConduitT void (Peer, PeerMessage e) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Peer
self,)) [PeerMessage e]
messages
          Peer -> MsgChan e -> ConduitT void (Peer, PeerMessage e) m ()
forall (m :: * -> *) e void.
MonadIO m =>
Peer -> MsgChan e -> ConduitT void (Peer, PeerMessage e) m ()
stream Peer
self (TVar (Maybe [PeerMessage e]) -> MsgChan e
forall e. TVar (Maybe [PeerMessage e]) -> MsgChan e
MsgChan TVar (Maybe [PeerMessage e])
chan)


{- | Enqueue a message to be sent. Return 'False' if the 'MsgChan' is closed.  -}
enqueueMsg :: (MonadIO m) => MsgChan e -> PeerMessage e -> m Bool
enqueueMsg :: forall (m :: * -> *) e.
MonadIO m =>
MsgChan e -> PeerMessage e -> m Bool
enqueueMsg (MsgChan TVar (Maybe [PeerMessage e])
chan) PeerMessage e
msg =
  m (m Bool) -> m Bool
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (m (m Bool) -> m Bool)
-> (STM (m Bool) -> m (m Bool)) -> STM (m Bool) -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (m Bool) -> m (m Bool)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (m Bool) -> m (m Bool))
-> (STM (m Bool) -> IO (m Bool)) -> STM (m Bool) -> m (m Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM (m Bool) -> IO (m Bool)
forall a. STM a -> IO a
atomically (STM (m Bool) -> m Bool) -> STM (m Bool) -> m Bool
forall a b. (a -> b) -> a -> b
$
    TVar (Maybe [PeerMessage e]) -> STM (Maybe [PeerMessage e])
forall a. TVar a -> STM a
readTVar TVar (Maybe [PeerMessage e])
chan STM (Maybe [PeerMessage e])
-> (Maybe [PeerMessage e] -> STM (m Bool)) -> STM (m Bool)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Maybe [PeerMessage e]
Nothing -> m Bool -> STM (m Bool)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False)
      Just [PeerMessage e]
msgs -> do
        TVar (Maybe [PeerMessage e]) -> Maybe [PeerMessage e] -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar (Maybe [PeerMessage e])
chan (
            [PeerMessage e] -> Maybe [PeerMessage e]
forall a. a -> Maybe a
Just ([PeerMessage e] -> Maybe [PeerMessage e])
-> [PeerMessage e] -> Maybe [PeerMessage e]
forall a b. (a -> b) -> a -> b
$ case PeerMessage e
msg of
              PMMerge Diff ClusterName Peer e
_ ->
                PeerMessage e
msg PeerMessage e -> [PeerMessage e] -> [PeerMessage e]
forall a. a -> [a] -> [a]
: (PeerMessage e -> Bool) -> [PeerMessage e] -> [PeerMessage e]
forall a. (a -> Bool) -> [a] -> [a]
filter
                        (\case {PMMerge Diff ClusterName Peer e
_ -> Bool
False; PeerMessage e
_ -> Bool
True})
                        [PeerMessage e]
msgs
              PMFullMerge EventFold ClusterName Peer e
_ ->
                {-
                  Full merges override both older full merges and
                  older partial merges.
                -}
                PeerMessage e
msg PeerMessage e -> [PeerMessage e] -> [PeerMessage e]
forall a. a -> [a] -> [a]
: (PeerMessage e -> Bool) -> [PeerMessage e] -> [PeerMessage e]
forall a. (a -> Bool) -> [a] -> [a]
filter
                        (\case
                          PMMerge Diff ClusterName Peer e
_ -> Bool
False
                          PMFullMerge EventFold ClusterName Peer e
_ -> Bool
False
                          PeerMessage e
_ -> Bool
True
                        )
                        [PeerMessage e]
msgs
              PeerMessage e
_ -> [PeerMessage e]
msgs [PeerMessage e] -> [PeerMessage e] -> [PeerMessage e]
forall a. [a] -> [a] -> [a]
++ [PeerMessage e
msg] 
          )
        m Bool -> STM (m Bool)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True)


{- | The types of messages that can be sent from one peer to another. -}
data PeerMessage e
  = PMMerge (Diff ClusterName Peer e)
    {- ^ Send a powerstate merge. -}
  | PMFullMerge (EventFold ClusterName Peer e)
    {- ^ Send a full merge. -}
  | PMCall Peer MessageId ByteString
    {- ^ Send a user call message from one peer to another. -}
  | PMCast ByteString
    {- ^ Send a user cast message from one peer to another. -}
  | PMCallResponse Peer MessageId ByteString
    {- ^ Send a response to a user call message. -}
  | PMOutputs (Map (EventId Peer) (Output e))
    {- ^ Send outputs to the appropriate recipient. -}
  deriving stock ((forall x. PeerMessage e -> Rep (PeerMessage e) x)
-> (forall x. Rep (PeerMessage e) x -> PeerMessage e)
-> Generic (PeerMessage e)
forall x. Rep (PeerMessage e) x -> PeerMessage e
forall x. PeerMessage e -> Rep (PeerMessage e) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall e x. Rep (PeerMessage e) x -> PeerMessage e
forall e x. PeerMessage e -> Rep (PeerMessage e) x
$cto :: forall e x. Rep (PeerMessage e) x -> PeerMessage e
$cfrom :: forall e x. PeerMessage e -> Rep (PeerMessage e) x
Generic)
deriving stock instance
    ( Show e
    , Show (Output e)
    , Show (State e)
    )
  =>
    Show (PeerMessage e)
instance (Binary e, Binary (Output e), Binary (State e)) => Binary (PeerMessage e)


{- | The identification of a node within the legion cluster. -}
newtype Peer = Peer
  { Peer -> Text
unPeer :: Text
  }
  deriving newtype (
    Peer -> Peer -> Bool
(Peer -> Peer -> Bool) -> (Peer -> Peer -> Bool) -> Eq Peer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Peer -> Peer -> Bool
$c/= :: Peer -> Peer -> Bool
== :: Peer -> Peer -> Bool
$c== :: Peer -> Peer -> Bool
Eq, Eq Peer
Eq Peer
-> (Peer -> Peer -> Ordering)
-> (Peer -> Peer -> Bool)
-> (Peer -> Peer -> Bool)
-> (Peer -> Peer -> Bool)
-> (Peer -> Peer -> Bool)
-> (Peer -> Peer -> Peer)
-> (Peer -> Peer -> Peer)
-> Ord Peer
Peer -> Peer -> Bool
Peer -> Peer -> Ordering
Peer -> Peer -> Peer
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Peer -> Peer -> Peer
$cmin :: Peer -> Peer -> Peer
max :: Peer -> Peer -> Peer
$cmax :: Peer -> Peer -> Peer
>= :: Peer -> Peer -> Bool
$c>= :: Peer -> Peer -> Bool
> :: Peer -> Peer -> Bool
$c> :: Peer -> Peer -> Bool
<= :: Peer -> Peer -> Bool
$c<= :: Peer -> Peer -> Bool
< :: Peer -> Peer -> Bool
$c< :: Peer -> Peer -> Bool
compare :: Peer -> Peer -> Ordering
$ccompare :: Peer -> Peer -> Ordering
Ord, Int -> Peer -> ShowS
[Peer] -> ShowS
Peer -> String
(Int -> Peer -> ShowS)
-> (Peer -> String) -> ([Peer] -> ShowS) -> Show Peer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Peer] -> ShowS
$cshowList :: [Peer] -> ShowS
show :: Peer -> String
$cshow :: Peer -> String
showsPrec :: Int -> Peer -> ShowS
$cshowsPrec :: Int -> Peer -> ShowS
Show, [Peer] -> Encoding
[Peer] -> Value
Peer -> Encoding
Peer -> Value
(Peer -> Value)
-> (Peer -> Encoding)
-> ([Peer] -> Value)
-> ([Peer] -> Encoding)
-> ToJSON Peer
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Peer] -> Encoding
$ctoEncodingList :: [Peer] -> Encoding
toJSONList :: [Peer] -> Value
$ctoJSONList :: [Peer] -> Value
toEncoding :: Peer -> Encoding
$ctoEncoding :: Peer -> Encoding
toJSON :: Peer -> Value
$ctoJSON :: Peer -> Value
ToJSON, Get Peer
[Peer] -> Put
Peer -> Put
(Peer -> Put) -> Get Peer -> ([Peer] -> Put) -> Binary Peer
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Peer] -> Put
$cputList :: [Peer] -> Put
get :: Get Peer
$cget :: Get Peer
put :: Peer -> Put
$cput :: Peer -> Put
Binary, ToJSONKeyFunction [Peer]
ToJSONKeyFunction Peer
ToJSONKeyFunction Peer
-> ToJSONKeyFunction [Peer] -> ToJSONKey Peer
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
toJSONKeyList :: ToJSONKeyFunction [Peer]
$ctoJSONKeyList :: ToJSONKeyFunction [Peer]
toJSONKey :: ToJSONKeyFunction Peer
$ctoJSONKey :: ToJSONKeyFunction Peer
ToJSONKey, Value -> Parser [Peer]
Value -> Parser Peer
(Value -> Parser Peer) -> (Value -> Parser [Peer]) -> FromJSON Peer
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Peer]
$cparseJSONList :: Value -> Parser [Peer]
parseJSON :: Value -> Parser Peer
$cparseJSON :: Value -> Parser Peer
FromJSON, FromJSONKeyFunction [Peer]
FromJSONKeyFunction Peer
FromJSONKeyFunction Peer
-> FromJSONKeyFunction [Peer] -> FromJSONKey Peer
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
fromJSONKeyList :: FromJSONKeyFunction [Peer]
$cfromJSONKeyList :: FromJSONKeyFunction [Peer]
fromJSONKey :: FromJSONKeyFunction Peer
$cfromJSONKey :: FromJSONKeyFunction Peer
FromJSONKey,
    ByteString -> Either Text Peer
Text -> Either Text Peer
(Text -> Either Text Peer)
-> (ByteString -> Either Text Peer)
-> (Text -> Either Text Peer)
-> FromHttpApiData Peer
forall a.
(Text -> Either Text a)
-> (ByteString -> Either Text a)
-> (Text -> Either Text a)
-> FromHttpApiData a
parseQueryParam :: Text -> Either Text Peer
$cparseQueryParam :: Text -> Either Text Peer
parseHeader :: ByteString -> Either Text Peer
$cparseHeader :: ByteString -> Either Text Peer
parseUrlPiece :: Text -> Either Text Peer
$cparseUrlPiece :: Text -> Either Text Peer
FromHttpApiData, Peer -> ByteString
Peer -> Builder
Peer -> Text
(Peer -> Text)
-> (Peer -> Builder)
-> (Peer -> ByteString)
-> (Peer -> Text)
-> ToHttpApiData Peer
forall a.
(a -> Text)
-> (a -> Builder)
-> (a -> ByteString)
-> (a -> Text)
-> ToHttpApiData a
toQueryParam :: Peer -> Text
$ctoQueryParam :: Peer -> Text
toHeader :: Peer -> ByteString
$ctoHeader :: Peer -> ByteString
toEncodedUrlPiece :: Peer -> Builder
$ctoEncodedUrlPiece :: Peer -> Builder
toUrlPiece :: Peer -> Text
$ctoUrlPiece :: Peer -> Text
ToHttpApiData
  )


{- | The name of a cluster. -}
newtype ClusterName = ClusterName
  { ClusterName -> Text
unClusterName :: Text
  }
  deriving newtype (
    String -> ClusterName
(String -> ClusterName) -> IsString ClusterName
forall a. (String -> a) -> IsString a
fromString :: String -> ClusterName
$cfromString :: String -> ClusterName
IsString, Int -> ClusterName -> ShowS
[ClusterName] -> ShowS
ClusterName -> String
(Int -> ClusterName -> ShowS)
-> (ClusterName -> String)
-> ([ClusterName] -> ShowS)
-> Show ClusterName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ClusterName] -> ShowS
$cshowList :: [ClusterName] -> ShowS
show :: ClusterName -> String
$cshow :: ClusterName -> String
showsPrec :: Int -> ClusterName -> ShowS
$cshowsPrec :: Int -> ClusterName -> ShowS
Show, Get ClusterName
[ClusterName] -> Put
ClusterName -> Put
(ClusterName -> Put)
-> Get ClusterName -> ([ClusterName] -> Put) -> Binary ClusterName
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [ClusterName] -> Put
$cputList :: [ClusterName] -> Put
get :: Get ClusterName
$cget :: Get ClusterName
put :: ClusterName -> Put
$cput :: ClusterName -> Put
Binary, ClusterName -> ClusterName -> Bool
(ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> Bool) -> Eq ClusterName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ClusterName -> ClusterName -> Bool
$c/= :: ClusterName -> ClusterName -> Bool
== :: ClusterName -> ClusterName -> Bool
$c== :: ClusterName -> ClusterName -> Bool
Eq, [ClusterName] -> Encoding
[ClusterName] -> Value
ClusterName -> Encoding
ClusterName -> Value
(ClusterName -> Value)
-> (ClusterName -> Encoding)
-> ([ClusterName] -> Value)
-> ([ClusterName] -> Encoding)
-> ToJSON ClusterName
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [ClusterName] -> Encoding
$ctoEncodingList :: [ClusterName] -> Encoding
toJSONList :: [ClusterName] -> Value
$ctoJSONList :: [ClusterName] -> Value
toEncoding :: ClusterName -> Encoding
$ctoEncoding :: ClusterName -> Encoding
toJSON :: ClusterName -> Value
$ctoJSON :: ClusterName -> Value
ToJSON, Value -> Parser [ClusterName]
Value -> Parser ClusterName
(Value -> Parser ClusterName)
-> (Value -> Parser [ClusterName]) -> FromJSON ClusterName
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [ClusterName]
$cparseJSONList :: Value -> Parser [ClusterName]
parseJSON :: Value -> Parser ClusterName
$cparseJSON :: Value -> Parser ClusterName
FromJSON, Eq ClusterName
Eq ClusterName
-> (ClusterName -> ClusterName -> Ordering)
-> (ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> Bool)
-> (ClusterName -> ClusterName -> ClusterName)
-> (ClusterName -> ClusterName -> ClusterName)
-> Ord ClusterName
ClusterName -> ClusterName -> Bool
ClusterName -> ClusterName -> Ordering
ClusterName -> ClusterName -> ClusterName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ClusterName -> ClusterName -> ClusterName
$cmin :: ClusterName -> ClusterName -> ClusterName
max :: ClusterName -> ClusterName -> ClusterName
$cmax :: ClusterName -> ClusterName -> ClusterName
>= :: ClusterName -> ClusterName -> Bool
$c>= :: ClusterName -> ClusterName -> Bool
> :: ClusterName -> ClusterName -> Bool
$c> :: ClusterName -> ClusterName -> Bool
<= :: ClusterName -> ClusterName -> Bool
$c<= :: ClusterName -> ClusterName -> Bool
< :: ClusterName -> ClusterName -> Bool
$c< :: ClusterName -> ClusterName -> Bool
compare :: ClusterName -> ClusterName -> Ordering
$ccompare :: ClusterName -> ClusterName -> Ordering
Ord, ClusterName -> ByteString
ClusterName -> Builder
ClusterName -> Text
(ClusterName -> Text)
-> (ClusterName -> Builder)
-> (ClusterName -> ByteString)
-> (ClusterName -> Text)
-> ToHttpApiData ClusterName
forall a.
(a -> Text)
-> (a -> Builder)
-> (a -> ByteString)
-> (a -> Text)
-> ToHttpApiData a
toQueryParam :: ClusterName -> Text
$ctoQueryParam :: ClusterName -> Text
toHeader :: ClusterName -> ByteString
$ctoHeader :: ClusterName -> ByteString
toEncodedUrlPiece :: ClusterName -> Builder
$ctoEncodedUrlPiece :: ClusterName -> Builder
toUrlPiece :: ClusterName -> Text
$ctoUrlPiece :: ClusterName -> Text
ToHttpApiData,
    ByteString -> Either Text ClusterName
Text -> Either Text ClusterName
(Text -> Either Text ClusterName)
-> (ByteString -> Either Text ClusterName)
-> (Text -> Either Text ClusterName)
-> FromHttpApiData ClusterName
forall a.
(Text -> Either Text a)
-> (ByteString -> Either Text a)
-> (Text -> Either Text a)
-> FromHttpApiData a
parseQueryParam :: Text -> Either Text ClusterName
$cparseQueryParam :: Text -> Either Text ClusterName
parseHeader :: ByteString -> Either Text ClusterName
$cparseHeader :: ByteString -> Either Text ClusterName
parseUrlPiece :: Text -> Either Text ClusterName
$cparseUrlPiece :: Text -> Either Text ClusterName
FromHttpApiData
  )


{- | Message Identifier. -}
data MessageId = M UUID Word64 deriving stock ((forall x. MessageId -> Rep MessageId x)
-> (forall x. Rep MessageId x -> MessageId) -> Generic MessageId
forall x. Rep MessageId x -> MessageId
forall x. MessageId -> Rep MessageId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MessageId x -> MessageId
$cfrom :: forall x. MessageId -> Rep MessageId x
Generic, Int -> MessageId -> ShowS
[MessageId] -> ShowS
MessageId -> String
(Int -> MessageId -> ShowS)
-> (MessageId -> String)
-> ([MessageId] -> ShowS)
-> Show MessageId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MessageId] -> ShowS
$cshowList :: [MessageId] -> ShowS
show :: MessageId -> String
$cshow :: MessageId -> String
showsPrec :: Int -> MessageId -> ShowS
$cshowsPrec :: Int -> MessageId -> ShowS
Show, MessageId -> MessageId -> Bool
(MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> Bool) -> Eq MessageId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MessageId -> MessageId -> Bool
$c/= :: MessageId -> MessageId -> Bool
== :: MessageId -> MessageId -> Bool
$c== :: MessageId -> MessageId -> Bool
Eq, Eq MessageId
Eq MessageId
-> (MessageId -> MessageId -> Ordering)
-> (MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> Bool)
-> (MessageId -> MessageId -> MessageId)
-> (MessageId -> MessageId -> MessageId)
-> Ord MessageId
MessageId -> MessageId -> Bool
MessageId -> MessageId -> Ordering
MessageId -> MessageId -> MessageId
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MessageId -> MessageId -> MessageId
$cmin :: MessageId -> MessageId -> MessageId
max :: MessageId -> MessageId -> MessageId
$cmax :: MessageId -> MessageId -> MessageId
>= :: MessageId -> MessageId -> Bool
$c>= :: MessageId -> MessageId -> Bool
> :: MessageId -> MessageId -> Bool
$c> :: MessageId -> MessageId -> Bool
<= :: MessageId -> MessageId -> Bool
$c<= :: MessageId -> MessageId -> Bool
< :: MessageId -> MessageId -> Bool
$c< :: MessageId -> MessageId -> Bool
compare :: MessageId -> MessageId -> Ordering
$ccompare :: MessageId -> MessageId -> Ordering
Ord)
instance Binary MessageId