{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TemplateHaskell #-}

----------------------------------------------------------------------

----------------------------------------------------------------------

-- |
-- Module: Web.Slack.Common
-- Description:
module Web.Slack.Common (
  Color (..),
  UserId (..),
  ConversationId (..),
  TeamId (..),
  Cursor (..),
  SlackTimestamp (..),
  mkSlackTimestamp,
  timestampFromText,
  Message (..),
  MessageType (..),
  SlackClientError (..),
  SlackMessageText (..),
) where

-- FIXME: Web.Slack.Prelude

-- aeson

-- base

-- deepseq
import Control.DeepSeq (NFData)
import Control.Exception
import Data.Aeson
import Data.Aeson.TH
-- servant-client

-- slack-web

-- text
import Data.Text (Text)
import GHC.Generics (Generic)
import Servant.Client
import Web.Slack.Types
import Web.Slack.Util
import Prelude

#if !MIN_VERSION_servant(0,16,0)
type ClientError = ServantError
#endif

data MessageType = MessageTypeMessage
  deriving stock (MessageType -> MessageType -> Bool
(MessageType -> MessageType -> Bool)
-> (MessageType -> MessageType -> Bool) -> Eq MessageType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MessageType -> MessageType -> Bool
== :: MessageType -> MessageType -> Bool
$c/= :: MessageType -> MessageType -> Bool
/= :: MessageType -> MessageType -> Bool
Eq, Int -> MessageType -> ShowS
[MessageType] -> ShowS
MessageType -> String
(Int -> MessageType -> ShowS)
-> (MessageType -> String)
-> ([MessageType] -> ShowS)
-> Show MessageType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MessageType -> ShowS
showsPrec :: Int -> MessageType -> ShowS
$cshow :: MessageType -> String
show :: MessageType -> String
$cshowList :: [MessageType] -> ShowS
showList :: [MessageType] -> ShowS
Show, (forall x. MessageType -> Rep MessageType x)
-> (forall x. Rep MessageType x -> MessageType)
-> Generic MessageType
forall x. Rep MessageType x -> MessageType
forall x. MessageType -> Rep MessageType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. MessageType -> Rep MessageType x
from :: forall x. MessageType -> Rep MessageType x
$cto :: forall x. Rep MessageType x -> MessageType
to :: forall x. Rep MessageType x -> MessageType
Generic)

instance NFData MessageType

instance FromJSON MessageType where
  parseJSON :: Value -> Parser MessageType
parseJSON Value
"message" = MessageType -> Parser MessageType
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
MessageTypeMessage
  parseJSON Value
_ = String -> Parser MessageType
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Invalid MessageType"

instance ToJSON MessageType where
  toJSON :: MessageType -> Value
toJSON MessageType
_ = Text -> Value
String Text
"message"

data Message = Message
  { Message -> MessageType
messageType :: MessageType
  , Message -> Maybe UserId
messageUser :: Maybe UserId
  -- ^ not present for bot messages at least
  , Message -> SlackMessageText
messageText :: SlackMessageText
  -- ^ the message text is in a markdown-like slack-specific format.
  -- Use 'Web.Slack.MessageParser.messageToHtml' to convert it to HTML.
  , Message -> SlackTimestamp
messageTs :: SlackTimestamp
  }
  deriving stock (Message -> Message -> Bool
(Message -> Message -> Bool)
-> (Message -> Message -> Bool) -> Eq Message
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Message -> Message -> Bool
== :: Message -> Message -> Bool
$c/= :: Message -> Message -> Bool
/= :: Message -> Message -> Bool
Eq, (forall x. Message -> Rep Message x)
-> (forall x. Rep Message x -> Message) -> Generic Message
forall x. Rep Message x -> Message
forall x. Message -> Rep Message x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Message -> Rep Message x
from :: forall x. Message -> Rep Message x
$cto :: forall x. Rep Message x -> Message
to :: forall x. Rep Message x -> Message
Generic, Int -> Message -> ShowS
[Message] -> ShowS
Message -> String
(Int -> Message -> ShowS)
-> (Message -> String) -> ([Message] -> ShowS) -> Show Message
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Message -> ShowS
showsPrec :: Int -> Message -> ShowS
$cshow :: Message -> String
show :: Message -> String
$cshowList :: [Message] -> ShowS
showList :: [Message] -> ShowS
Show)

instance NFData Message

$(deriveJSON (jsonOpts "message") ''Message)

-- |
-- Errors that can be triggered by a slack request.
data SlackClientError
  = -- | errors from the network connection
    ServantError ClientError
  | -- | errors returned by the slack API
    SlackError Text
  deriving stock (SlackClientError -> SlackClientError -> Bool
(SlackClientError -> SlackClientError -> Bool)
-> (SlackClientError -> SlackClientError -> Bool)
-> Eq SlackClientError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SlackClientError -> SlackClientError -> Bool
== :: SlackClientError -> SlackClientError -> Bool
$c/= :: SlackClientError -> SlackClientError -> Bool
/= :: SlackClientError -> SlackClientError -> Bool
Eq, (forall x. SlackClientError -> Rep SlackClientError x)
-> (forall x. Rep SlackClientError x -> SlackClientError)
-> Generic SlackClientError
forall x. Rep SlackClientError x -> SlackClientError
forall x. SlackClientError -> Rep SlackClientError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SlackClientError -> Rep SlackClientError x
from :: forall x. SlackClientError -> Rep SlackClientError x
$cto :: forall x. Rep SlackClientError x -> SlackClientError
to :: forall x. Rep SlackClientError x -> SlackClientError
Generic, Int -> SlackClientError -> ShowS
[SlackClientError] -> ShowS
SlackClientError -> String
(Int -> SlackClientError -> ShowS)
-> (SlackClientError -> String)
-> ([SlackClientError] -> ShowS)
-> Show SlackClientError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SlackClientError -> ShowS
showsPrec :: Int -> SlackClientError -> ShowS
$cshow :: SlackClientError -> String
show :: SlackClientError -> String
$cshowList :: [SlackClientError] -> ShowS
showList :: [SlackClientError] -> ShowS
Show)

instance NFData SlackClientError

instance Exception SlackClientError