{-| Module : Game.Werewolf.Response Description : Response and message data structures. Copyright : (c) Henry J. Wylde, 2016 License : BSD3 Maintainer : public@hjwylde.com A response is used as a return result of calling the @werewolf@ binary. Each response has a list of associated messages. @werewolf@ was designed to be ambivalent to the playing chat client. The response-message structure reflects this by staying away from anything that could be construed as client-specific. This includes features such as emoji support. -} {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} module Game.Werewolf.Response ( -- * Response Response(..), -- ** Common responses success, failure, -- ** Exit functions exitWith, -- * Message Message(..), publicMessage, privateMessage, groupMessages, ) where import Control.Monad.IO.Class import Data.Aeson #if !MIN_VERSION_aeson(0,10,0) import Data.Aeson.Types #endif import Data.Text (Text) import qualified Data.Text.Lazy.Encoding as T import qualified Data.Text.Lazy.IO as T import GHC.Generics import qualified System.Exit as Exit -- | When a user sends a command to the @werewolf@ binary, a response is always returned. -- -- The chat interface should then relay any @messages@ from the response. Whether or not the -- command was valid (indicated by the @ok@ flag) is often irrelevant as the returned @messages@ -- will include errors to the user. data Response = Response { ok :: Bool -- ^ Boolean flag to indicate success. , messages :: [Message] -- ^ List of messages. } deriving (Eq, Generic, Show) instance FromJSON Response instance ToJSON Response where toJSON = genericToJSON defaultOptions #if MIN_VERSION_aeson(0,10,0) toEncoding = genericToEncoding defaultOptions #endif -- | A successful, empty response. success :: Response success = Response True [] -- | An unsuccessful, empty response. failure :: Response failure = Response False [] -- | Exits fast with the given response. The response is encoded as JSON, printed to @stdout@ and -- then the program is exited with @0@ (success). -- -- The program always exits with success even if the response was a failure one. This is to -- distinguish between bad calls to the binary and bad commands to the werewolf engine. exitWith :: MonadIO m => Response -> m a exitWith response = liftIO $ T.putStrLn (T.decodeUtf8 $ encode response) >> Exit.exitSuccess -- | A message may be either public or private, indicated by its @to@ field. -- -- Each message contains a single text field. This field is permitted to contain special -- characters such as new lines and tabs. data Message = Message { to :: Maybe Text -- ^ The message recipient: 'Nothing' for a public message, -- 'Just' for a private message. , message :: Text -- ^ The message text. } deriving (Eq, Generic, Show) instance FromJSON Message instance ToJSON Message where toJSON = genericToJSON defaultOptions #if MIN_VERSION_aeson(0,10,0) toEncoding = genericToEncoding defaultOptions #endif -- | Creates a public message with the given text. publicMessage :: Text -> Message publicMessage = Message Nothing -- | @privateMessage to message@ -- -- Creates a private message to @to@ with the given text. privateMessage :: Text -> Text -> Message privateMessage to = Message (Just to) -- | @groupMessages tos message@ -- -- Creates multiple private messages (1 to each recipient) with the given text. groupMessages :: [Text] -> Text -> [Message] groupMessages tos message = map (`privateMessage` message) tos