module Ouroboros.Network.Subscription.Subscriber
  ( SubscriptionTarget (..)
  , listSubscriptionTarget
  ) where

-- | Generate subscription targets in some monad.
-- Examples include obtaining targets from a fixed list, or from a DNS lookup.
newtype SubscriptionTarget m target = SubscriptionTarget
    { forall (m :: * -> *) target.
SubscriptionTarget m target
-> m (Maybe (target, SubscriptionTarget m target))
getSubscriptionTarget :: m (Maybe (target, SubscriptionTarget m target))
      -- ^ This should be used with the exception that implementations can block on
      -- the order of seconds.
    }

listSubscriptionTarget
    :: Applicative m
    => [target]
    -> SubscriptionTarget m target
listSubscriptionTarget :: forall (m :: * -> *) target.
Applicative m =>
[target] -> SubscriptionTarget m target
listSubscriptionTarget []     = m (Maybe (target, SubscriptionTarget m target))
-> SubscriptionTarget m target
forall (m :: * -> *) target.
m (Maybe (target, SubscriptionTarget m target))
-> SubscriptionTarget m target
SubscriptionTarget (m (Maybe (target, SubscriptionTarget m target))
 -> SubscriptionTarget m target)
-> m (Maybe (target, SubscriptionTarget m target))
-> SubscriptionTarget m target
forall a b. (a -> b) -> a -> b
$ Maybe (target, SubscriptionTarget m target)
-> m (Maybe (target, SubscriptionTarget m target))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (target, SubscriptionTarget m target)
forall a. Maybe a
Nothing
listSubscriptionTarget (target
t:[target]
ts) = m (Maybe (target, SubscriptionTarget m target))
-> SubscriptionTarget m target
forall (m :: * -> *) target.
m (Maybe (target, SubscriptionTarget m target))
-> SubscriptionTarget m target
SubscriptionTarget (m (Maybe (target, SubscriptionTarget m target))
 -> SubscriptionTarget m target)
-> m (Maybe (target, SubscriptionTarget m target))
-> SubscriptionTarget m target
forall a b. (a -> b) -> a -> b
$ Maybe (target, SubscriptionTarget m target)
-> m (Maybe (target, SubscriptionTarget m target))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((target, SubscriptionTarget m target)
-> Maybe (target, SubscriptionTarget m target)
forall a. a -> Maybe a
Just (target
t, [target] -> SubscriptionTarget m target
forall (m :: * -> *) target.
Applicative m =>
[target] -> SubscriptionTarget m target
listSubscriptionTarget [target]
ts))