{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}

-- |
-- Module      : Network.Reddit.Types.Message
-- Copyright   : (c) 2021 Rory Tyler Hayford
-- License     : BSD-3-Clause
-- Maintainer  : rory.hayford@protonmail.com
-- Stability   : experimental
-- Portability : GHC
--
module Network.Reddit.Types.Message
    ( Message(..)
    , PrivateMessageID(PrivateMessageID)
    , MessageID(..)
    , MessageOpts(..)
    , NewMessage(..)
    , PostedMessage
    ) where

import           Data.Aeson
                 ( (.:)
                 , FromJSON(..)
                 , Object
                 , Options(sumEncoding)
                 , SumEncoding(UntaggedValue)
                 , Value(..)
                 , defaultOptions
                 , genericParseJSON
                 , withObject
                 , withText
                 )
import           Data.Aeson.Types              ( Parser )
import           Data.Coerce                   ( coerce )
import           Data.Generics.Product         ( HasField(field) )
import           Data.Sequence                 ( Seq )
import           Data.Text                     ( Text )
import           Data.Time                     ( UTCTime )

import           GHC.Exts                      ( IsList(fromList) )
import           GHC.Generics                  ( Generic )

import           Lens.Micro

import           Network.Reddit.Types.Account
import           Network.Reddit.Types.Comment  ( CommentID )
import           Network.Reddit.Types.Internal

import           Web.FormUrlEncoded            ( ToForm(..) )
import           Web.HttpApiData               ( ToHttpApiData(toQueryParam) )

-- | A private message or comment reply
data Message = Message
    { Message -> MessageID
messageID :: MessageID
    , Message -> Username
author    :: Username
    , Message -> Username
dest      :: Username
    , Message -> Body
body      :: Body
    , Message -> Body
bodyHTML  :: Body
    , Message -> Body
subject   :: Subject
    , Message -> UTCTime
created   :: UTCTime
    , Message -> Bool
new       :: Bool
    , Message -> Seq Message
replies   :: Seq Message
    }
    deriving stock ( 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
showList :: [Message] -> ShowS
$cshowList :: [Message] -> ShowS
show :: Message -> String
$cshow :: Message -> String
showsPrec :: Int -> Message -> ShowS
$cshowsPrec :: Int -> Message -> ShowS
Show, Message -> Message -> Bool
(Message -> Message -> Bool)
-> (Message -> Message -> Bool) -> Eq Message
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Message -> Message -> Bool
$c/= :: Message -> Message -> Bool
== :: Message -> Message -> Bool
$c== :: 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
$cto :: forall x. Rep Message x -> Message
$cfrom :: forall x. Message -> Rep Message x
Generic )

instance FromJSON Message where
    parseJSON :: Value -> Parser Message
parseJSON = [RedditKind]
-> String -> (Object -> Parser Message) -> Value -> Parser Message
forall b a.
FromJSON b =>
[RedditKind] -> String -> (b -> Parser a) -> Value -> Parser a
withKinds [ RedditKind
MessageKind, RedditKind
CommentKind ] String
"Message" Object -> Parser Message
messageP

messageP :: Object -> Parser Message
messageP :: Object -> Parser Message
messageP Object
o = MessageID
-> Username
-> Username
-> Body
-> Body
-> Body
-> UTCTime
-> Bool
-> Seq Message
-> Message
Message (MessageID
 -> Username
 -> Username
 -> Body
 -> Body
 -> Body
 -> UTCTime
 -> Bool
 -> Seq Message
 -> Message)
-> Parser MessageID
-> Parser
     (Username
      -> Username
      -> Body
      -> Body
      -> Body
      -> UTCTime
      -> Bool
      -> Seq Message
      -> Message)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Object
o Object -> Body -> Parser MessageID
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"name")
    Parser
  (Username
   -> Username
   -> Body
   -> Body
   -> Body
   -> UTCTime
   -> Bool
   -> Seq Message
   -> Message)
-> Parser Username
-> Parser
     (Username
      -> Body
      -> Body
      -> Body
      -> UTCTime
      -> Bool
      -> Seq Message
      -> Message)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
o Object -> Body -> Parser Username
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"author")
    Parser
  (Username
   -> Body
   -> Body
   -> Body
   -> UTCTime
   -> Bool
   -> Seq Message
   -> Message)
-> Parser Username
-> Parser
     (Body -> Body -> Body -> UTCTime -> Bool -> Seq Message -> Message)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
o Object -> Body -> Parser Username
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"dest")
    Parser
  (Body -> Body -> Body -> UTCTime -> Bool -> Seq Message -> Message)
-> Parser Body
-> Parser
     (Body -> Body -> UTCTime -> Bool -> Seq Message -> Message)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
o Object -> Body -> Parser Body
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"body")
    Parser (Body -> Body -> UTCTime -> Bool -> Seq Message -> Message)
-> Parser Body
-> Parser (Body -> UTCTime -> Bool -> Seq Message -> Message)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
o Object -> Body -> Parser Body
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"body_html")
    Parser (Body -> UTCTime -> Bool -> Seq Message -> Message)
-> Parser Body
-> Parser (UTCTime -> Bool -> Seq Message -> Message)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
o Object -> Body -> Parser Body
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"subject")
    Parser (UTCTime -> Bool -> Seq Message -> Message)
-> Parser UTCTime -> Parser (Bool -> Seq Message -> Message)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Integer -> UTCTime
integerToUTC (Integer -> UTCTime) -> Parser Integer -> Parser UTCTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Body -> Parser Integer
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"created")
    Parser (Bool -> Seq Message -> Message)
-> Parser Bool -> Parser (Seq Message -> Message)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
o Object -> Body -> Parser Bool
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"new")
    Parser (Seq Message -> Message)
-> Parser (Seq Message) -> Parser Message
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Value -> Parser (Seq Message)
repliesP (Value -> Parser (Seq Message))
-> Parser Value -> Parser (Seq Message)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Body -> Parser Value
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"replies")
  where
    repliesP :: Value -> Parser (Seq Message)
repliesP (String Body
_)   = Seq Message -> Parser (Seq Message)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Seq Message
forall a. Monoid a => a
mempty
    repliesP v :: Value
v@(Object Object
_) = Value -> Parser (Listing MessageID Message)
forall a. FromJSON a => Value -> Parser a
parseJSON @(Listing MessageID Message) Value
v
        Parser (Listing MessageID Message)
-> (Listing MessageID Message -> Seq Message)
-> Parser (Seq Message)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (Listing MessageID Message
-> Getting (Seq Message) (Listing MessageID Message) (Seq Message)
-> Seq Message
forall s a. s -> Getting a s a -> a
^. forall s t a b. HasField "children" s t a b => Lens s t a b
forall (field :: Symbol) s t a b.
HasField field s t a b =>
Lens s t a b
field @"children")
    repliesP Value
_            = Parser (Seq Message)
forall a. Monoid a => a
mempty

instance Paginable Message where
    type PaginateOptions Message = MessageOpts

    type PaginateThing Message = MessageID

    defaultOpts :: PaginateOptions Message
defaultOpts = MessageOpts :: Bool -> MessageOpts
MessageOpts { $sel:mark:MessageOpts :: Bool
mark = Bool
False }

    getFullname :: Message -> PaginateThing Message
getFullname Message { MessageID
messageID :: MessageID
$sel:messageID:Message :: Message -> MessageID
messageID } = PaginateThing Message
MessageID
messageID

-- | Options for requesting and paginating 'Listing's of 'Message's
data MessageOpts = MessageOpts
    { -- | If set to @False@ (the default), any new messages read via the API
      -- will maintain their unread status in the web UI
      MessageOpts -> Bool
mark :: Bool
    }
    deriving stock ( Int -> MessageOpts -> ShowS
[MessageOpts] -> ShowS
MessageOpts -> String
(Int -> MessageOpts -> ShowS)
-> (MessageOpts -> String)
-> ([MessageOpts] -> ShowS)
-> Show MessageOpts
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MessageOpts] -> ShowS
$cshowList :: [MessageOpts] -> ShowS
show :: MessageOpts -> String
$cshow :: MessageOpts -> String
showsPrec :: Int -> MessageOpts -> ShowS
$cshowsPrec :: Int -> MessageOpts -> ShowS
Show, MessageOpts -> MessageOpts -> Bool
(MessageOpts -> MessageOpts -> Bool)
-> (MessageOpts -> MessageOpts -> Bool) -> Eq MessageOpts
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MessageOpts -> MessageOpts -> Bool
$c/= :: MessageOpts -> MessageOpts -> Bool
== :: MessageOpts -> MessageOpts -> Bool
$c== :: MessageOpts -> MessageOpts -> Bool
Eq, (forall x. MessageOpts -> Rep MessageOpts x)
-> (forall x. Rep MessageOpts x -> MessageOpts)
-> Generic MessageOpts
forall x. Rep MessageOpts x -> MessageOpts
forall x. MessageOpts -> Rep MessageOpts x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MessageOpts x -> MessageOpts
$cfrom :: forall x. MessageOpts -> Rep MessageOpts x
Generic )

instance ToForm MessageOpts where
    toForm :: MessageOpts -> Form
toForm MessageOpts { Bool
mark :: Bool
$sel:mark:MessageOpts :: MessageOpts -> Bool
.. } = [Item Form] -> Form
forall l. IsList l => [Item l] -> l
fromList [ (Body
"mark", Bool -> Body
forall a. ToHttpApiData a => a -> Body
toQueryParam Bool
mark) ]

-- | This can be 'CommentID' for replies to a comment, or a 'PrivateMessageID'
-- for private messages. Querying one's inbox or unread messages can provide
-- both types
data MessageID
    = CommentReply CommentID
    | PrivateMessage PrivateMessageID
    deriving stock ( 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, (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, 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
$cp1Ord :: Eq MessageID
Ord )

instance FromJSON MessageID where
    parseJSON :: Value -> Parser MessageID
parseJSON =
        Options -> Value -> Parser MessageID
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions { sumEncoding :: SumEncoding
sumEncoding = SumEncoding
UntaggedValue }

instance ToHttpApiData MessageID where
    toQueryParam :: MessageID -> Body
toQueryParam (CommentReply CommentID
cid)   = CommentID -> Body
forall a. ToHttpApiData a => a -> Body
toQueryParam CommentID
cid
    toQueryParam (PrivateMessage PrivateMessageID
mid) = PrivateMessageID -> Body
forall a. ToHttpApiData a => a -> Body
toQueryParam PrivateMessageID
mid

instance Thing MessageID where
    fullname :: MessageID -> Body
fullname (CommentReply CommentID
cid)   = CommentID -> Body
forall a. Thing a => a -> Body
fullname CommentID
cid
    fullname (PrivateMessage PrivateMessageID
mid) = PrivateMessageID -> Body
forall a. Thing a => a -> Body
fullname PrivateMessageID
mid

-- | A private message ID
newtype PrivateMessageID = PrivateMessageID Text
    deriving stock ( Int -> PrivateMessageID -> ShowS
[PrivateMessageID] -> ShowS
PrivateMessageID -> String
(Int -> PrivateMessageID -> ShowS)
-> (PrivateMessageID -> String)
-> ([PrivateMessageID] -> ShowS)
-> Show PrivateMessageID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PrivateMessageID] -> ShowS
$cshowList :: [PrivateMessageID] -> ShowS
show :: PrivateMessageID -> String
$cshow :: PrivateMessageID -> String
showsPrec :: Int -> PrivateMessageID -> ShowS
$cshowsPrec :: Int -> PrivateMessageID -> ShowS
Show, (forall x. PrivateMessageID -> Rep PrivateMessageID x)
-> (forall x. Rep PrivateMessageID x -> PrivateMessageID)
-> Generic PrivateMessageID
forall x. Rep PrivateMessageID x -> PrivateMessageID
forall x. PrivateMessageID -> Rep PrivateMessageID x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PrivateMessageID x -> PrivateMessageID
$cfrom :: forall x. PrivateMessageID -> Rep PrivateMessageID x
Generic, Eq PrivateMessageID
Eq PrivateMessageID
-> (PrivateMessageID -> PrivateMessageID -> Ordering)
-> (PrivateMessageID -> PrivateMessageID -> Bool)
-> (PrivateMessageID -> PrivateMessageID -> Bool)
-> (PrivateMessageID -> PrivateMessageID -> Bool)
-> (PrivateMessageID -> PrivateMessageID -> Bool)
-> (PrivateMessageID -> PrivateMessageID -> PrivateMessageID)
-> (PrivateMessageID -> PrivateMessageID -> PrivateMessageID)
-> Ord PrivateMessageID
PrivateMessageID -> PrivateMessageID -> Bool
PrivateMessageID -> PrivateMessageID -> Ordering
PrivateMessageID -> PrivateMessageID -> PrivateMessageID
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 :: PrivateMessageID -> PrivateMessageID -> PrivateMessageID
$cmin :: PrivateMessageID -> PrivateMessageID -> PrivateMessageID
max :: PrivateMessageID -> PrivateMessageID -> PrivateMessageID
$cmax :: PrivateMessageID -> PrivateMessageID -> PrivateMessageID
>= :: PrivateMessageID -> PrivateMessageID -> Bool
$c>= :: PrivateMessageID -> PrivateMessageID -> Bool
> :: PrivateMessageID -> PrivateMessageID -> Bool
$c> :: PrivateMessageID -> PrivateMessageID -> Bool
<= :: PrivateMessageID -> PrivateMessageID -> Bool
$c<= :: PrivateMessageID -> PrivateMessageID -> Bool
< :: PrivateMessageID -> PrivateMessageID -> Bool
$c< :: PrivateMessageID -> PrivateMessageID -> Bool
compare :: PrivateMessageID -> PrivateMessageID -> Ordering
$ccompare :: PrivateMessageID -> PrivateMessageID -> Ordering
$cp1Ord :: Eq PrivateMessageID
Ord )
    deriving newtype ( PrivateMessageID -> PrivateMessageID -> Bool
(PrivateMessageID -> PrivateMessageID -> Bool)
-> (PrivateMessageID -> PrivateMessageID -> Bool)
-> Eq PrivateMessageID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PrivateMessageID -> PrivateMessageID -> Bool
$c/= :: PrivateMessageID -> PrivateMessageID -> Bool
== :: PrivateMessageID -> PrivateMessageID -> Bool
$c== :: PrivateMessageID -> PrivateMessageID -> Bool
Eq, PrivateMessageID -> ByteString
PrivateMessageID -> Builder
PrivateMessageID -> Body
(PrivateMessageID -> Body)
-> (PrivateMessageID -> Builder)
-> (PrivateMessageID -> ByteString)
-> (PrivateMessageID -> Body)
-> ToHttpApiData PrivateMessageID
forall a.
(a -> Body)
-> (a -> Builder)
-> (a -> ByteString)
-> (a -> Body)
-> ToHttpApiData a
toQueryParam :: PrivateMessageID -> Body
$ctoQueryParam :: PrivateMessageID -> Body
toHeader :: PrivateMessageID -> ByteString
$ctoHeader :: PrivateMessageID -> ByteString
toEncodedUrlPiece :: PrivateMessageID -> Builder
$ctoEncodedUrlPiece :: PrivateMessageID -> Builder
toUrlPiece :: PrivateMessageID -> Body
$ctoUrlPiece :: PrivateMessageID -> Body
ToHttpApiData )

instance FromJSON PrivateMessageID where
    parseJSON :: Value -> Parser PrivateMessageID
parseJSON =
        String
-> (Body -> Parser PrivateMessageID)
-> Value
-> Parser PrivateMessageID
forall a. String -> (Body -> Parser a) -> Value -> Parser a
withText String
"PrivateMessageID" (Parser Body -> Parser PrivateMessageID
coerce (Parser Body -> Parser PrivateMessageID)
-> (Body -> Parser Body) -> Body -> Parser PrivateMessageID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RedditKind -> Body -> Parser Body
dropTypePrefix RedditKind
MessageKind)

instance Thing PrivateMessageID where
    fullname :: PrivateMessageID -> Body
fullname = RedditKind -> Body -> Body
prependType RedditKind
MessageKind (Body -> Body)
-> (PrivateMessageID -> Body) -> PrivateMessageID -> Body
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrivateMessageID -> Body
coerce

-- | For sending new 'Message's via the @compose@ API endpoint
data NewMessage = NewMessage
    { -- | The subject should be <= 100 characters in length
      NewMessage -> Body
subject :: Subject
    , NewMessage -> Body
message :: Body
    , NewMessage -> Username
dest    :: Username
    }
    deriving stock ( Int -> NewMessage -> ShowS
[NewMessage] -> ShowS
NewMessage -> String
(Int -> NewMessage -> ShowS)
-> (NewMessage -> String)
-> ([NewMessage] -> ShowS)
-> Show NewMessage
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NewMessage] -> ShowS
$cshowList :: [NewMessage] -> ShowS
show :: NewMessage -> String
$cshow :: NewMessage -> String
showsPrec :: Int -> NewMessage -> ShowS
$cshowsPrec :: Int -> NewMessage -> ShowS
Show, NewMessage -> NewMessage -> Bool
(NewMessage -> NewMessage -> Bool)
-> (NewMessage -> NewMessage -> Bool) -> Eq NewMessage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NewMessage -> NewMessage -> Bool
$c/= :: NewMessage -> NewMessage -> Bool
== :: NewMessage -> NewMessage -> Bool
$c== :: NewMessage -> NewMessage -> Bool
Eq, (forall x. NewMessage -> Rep NewMessage x)
-> (forall x. Rep NewMessage x -> NewMessage) -> Generic NewMessage
forall x. Rep NewMessage x -> NewMessage
forall x. NewMessage -> Rep NewMessage x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep NewMessage x -> NewMessage
$cfrom :: forall x. NewMessage -> Rep NewMessage x
Generic )

instance ToForm NewMessage where
    toForm :: NewMessage -> Form
toForm NewMessage { Body
Username
dest :: Username
message :: Body
subject :: Body
$sel:dest:NewMessage :: NewMessage -> Username
$sel:message:NewMessage :: NewMessage -> Body
$sel:subject:NewMessage :: NewMessage -> Body
.. } =
        [Item Form] -> Form
forall l. IsList l => [Item l] -> l
fromList [ (Body
"to", Username -> Body
forall a. ToHttpApiData a => a -> Body
toQueryParam Username
dest)
                 , (Body
"subject", Body
subject)
                 , (Body
"text", Body
message)
                 ]

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

instance FromJSON PostedMessage where
    parseJSON :: Value -> Parser PostedMessage
parseJSON = String
-> (Object -> Parser PostedMessage)
-> Value
-> Parser PostedMessage
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"PostedMessage" ((Object -> Parser PostedMessage) -> Value -> Parser PostedMessage)
-> (Object -> Parser PostedMessage)
-> Value
-> Parser PostedMessage
forall a b. (a -> b) -> a -> b
$ \Object
o -> [Value] -> Parser PostedMessage
postedMessageP
        ([Value] -> Parser PostedMessage)
-> Parser [Value] -> Parser PostedMessage
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ((Object -> Body -> Parser [Value]
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"things") (Object -> Parser [Value]) -> Parser Object -> Parser [Value]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Object -> Body -> Parser Object
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"data") (Object -> Parser Object) -> Parser Object -> Parser Object
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Body -> Parser Object
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"json")
      where
        postedMessageP :: [Value] -> Parser PostedMessage
postedMessageP [ Object Object
o ] = Message -> PostedMessage
PostedMessage
            (Message -> PostedMessage)
-> Parser Message -> Parser PostedMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Object -> Parser Message
messageP (Object -> Parser Message) -> Parser Object -> Parser Message
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Body -> Parser Object
forall a. FromJSON a => Object -> Body -> Parser a
.: Body
"data")
        postedMessageP [Value]
_            = Parser PostedMessage
forall a. Monoid a => a
mempty