{-# LANGUAGE OverloadedStrings #-}

{-|
Module      : Pulsar.Types
Description : End-user Pulsar API types.
License     : Apache-2.0
Maintainer  : gabriel.volpe@chatroulette.com
Stability   : experimental

End-user types to configure consumers and producers.
-}
module Pulsar.Types where

import qualified Data.ByteString.Lazy.Char8    as CL
import           Data.Char                      ( toLower )
import           Data.String                    ( IsString
                                                , fromString
                                                )
import qualified Data.Text                     as T
import           Proto.PulsarApi                ( MessageIdData )

{- | A Topic is in the form "type:\/\/tenant\/namespace\/topic-name", which is what the 'Show' instance does. -}
data Topic = Topic
  { Topic -> TopicType
type' :: TopicType
  , Topic -> Tenant
tenant :: Tenant
  , Topic -> NameSpace
namespace :: NameSpace
  , Topic -> TopicName
name :: TopicName
  }

{- | A default 'Topic': "non-persistent:\/\/public\/default\/my-topic". -}
defaultTopic :: TopicName -> Topic
defaultTopic :: TopicName -> Topic
defaultTopic n :: TopicName
n = Topic :: TopicType -> Tenant -> NameSpace -> TopicName -> Topic
Topic { type' :: TopicType
type'     = TopicType
NonPersistent
                       , tenant :: Tenant
tenant    = "public"
                       , namespace :: NameSpace
namespace = "default"
                       , name :: TopicName
name      = TopicName
n
                       }

instance Show Topic where
  show :: Topic -> String
show (Topic typ :: TopicType
typ tn :: Tenant
tn ns :: NameSpace
ns n :: TopicName
n) =
    Char -> Char
toLower (Char -> Char) -> ShowS
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TopicType -> String
forall a. Show a => a -> String
show TopicType
typ String -> ShowS
forall a. Semigroup a => a -> a -> a
<> "://" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Tenant -> String
forall a. Show a => a -> String
show Tenant
tn String -> ShowS
forall a. Semigroup a => a -> a -> a
<> "/" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> NameSpace -> String
forall a. Show a => a -> String
show NameSpace
ns String -> ShowS
forall a. Semigroup a => a -> a -> a
<> "/" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TopicName -> String
forall a. Show a => a -> String
show TopicName
n

{- | A topic can be either 'Persistent' or 'NonPersistent'. -}
data TopicType = Persistent | NonPersistent

instance Show TopicType where
  show :: TopicType -> String
show Persistent    = "persistent"
  show NonPersistent = "non-persistent"

{- | A tenant can be any string value. Default value is "public". -}
newtype Tenant = Tenant T.Text

instance IsString Tenant where
  fromString :: String -> Tenant
fromString = Text -> Tenant
Tenant (Text -> Tenant) -> (String -> Text) -> String -> Tenant
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

instance Show Tenant where
  show :: Tenant -> String
show (Tenant t :: Text
t) = Text -> String
T.unpack Text
t

{- | A namespace can be any string value. Default value is "default". -}
newtype NameSpace = NameSpace T.Text

instance IsString NameSpace where
  fromString :: String -> NameSpace
fromString = Text -> NameSpace
NameSpace (Text -> NameSpace) -> (String -> Text) -> String -> NameSpace
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

instance Show NameSpace where
  show :: NameSpace -> String
show (NameSpace t :: Text
t) = Text -> String
T.unpack Text
t

{- | A topic name can be any string value. -}
newtype TopicName = TopicName T.Text

instance IsString TopicName where
  fromString :: String -> TopicName
fromString = Text -> TopicName
TopicName (Text -> TopicName) -> (String -> Text) -> String -> TopicName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

instance Show TopicName where
  show :: TopicName -> String
show (TopicName t :: Text
t) = Text -> String
T.unpack Text
t

{- | A message id, needed for acknowledging messages. See 'Pulsar.Consumer.ack'. -}
newtype MsgId = MsgId MessageIdData

{- | A consumed message, containing both 'MsgId' and payload as bytestring. -}
data Message = Message MsgId CL.ByteString

{- | A produced message, containing just a payload as bytestring. -}
newtype PulsarMessage = PulsarMessage CL.ByteString deriving Int -> PulsarMessage -> ShowS
[PulsarMessage] -> ShowS
PulsarMessage -> String
(Int -> PulsarMessage -> ShowS)
-> (PulsarMessage -> String)
-> ([PulsarMessage] -> ShowS)
-> Show PulsarMessage
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PulsarMessage] -> ShowS
$cshowList :: [PulsarMessage] -> ShowS
show :: PulsarMessage -> String
$cshow :: PulsarMessage -> String
showsPrec :: Int -> PulsarMessage -> ShowS
$cshowsPrec :: Int -> PulsarMessage -> ShowS
Show

instance IsString PulsarMessage where
  fromString :: String -> PulsarMessage
fromString = ByteString -> PulsarMessage
PulsarMessage (ByteString -> PulsarMessage)
-> (String -> ByteString) -> String -> PulsarMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
CL.pack

{- | A subscription name can be any string value. -}
newtype SubName = SubName T.Text deriving Int -> SubName -> ShowS
[SubName] -> ShowS
SubName -> String
(Int -> SubName -> ShowS)
-> (SubName -> String) -> ([SubName] -> ShowS) -> Show SubName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SubName] -> ShowS
$cshowList :: [SubName] -> ShowS
show :: SubName -> String
$cshow :: SubName -> String
showsPrec :: Int -> SubName -> ShowS
$cshowsPrec :: Int -> SubName -> ShowS
Show

instance IsString SubName where
  fromString :: String -> SubName
fromString = Text -> SubName
SubName (Text -> SubName) -> (String -> Text) -> String -> SubName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

{- | A subscription type. See <https://pulsar.apache.org/docs/en/concepts-messaging/#subscriptions> to learn more. -}
data SubType = Exclusive | Failover | Shared | KeyShared deriving Int -> SubType -> ShowS
[SubType] -> ShowS
SubType -> String
(Int -> SubType -> ShowS)
-> (SubType -> String) -> ([SubType] -> ShowS) -> Show SubType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SubType] -> ShowS
$cshowList :: [SubType] -> ShowS
show :: SubType -> String
$cshow :: SubType -> String
showsPrec :: Int -> SubType -> ShowS
$cshowsPrec :: Int -> SubType -> ShowS
Show

{- | A subscription with a type and a name. -}
data Subscription = Subscription SubType SubName deriving Int -> Subscription -> ShowS
[Subscription] -> ShowS
Subscription -> String
(Int -> Subscription -> ShowS)
-> (Subscription -> String)
-> ([Subscription] -> ShowS)
-> Show Subscription
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Subscription] -> ShowS
$cshowList :: [Subscription] -> ShowS
show :: Subscription -> String
$cshow :: Subscription -> String
showsPrec :: Int -> Subscription -> ShowS
$cshowsPrec :: Int -> Subscription -> ShowS
Show