\section{DHT Request Packets}
DHT Request packets are used to route encrypted data from a sender to another
node, referred to as the addressee of the packet, via a third node.

A DHT Request Packet is sent as the payload of a Protocol Packet with the
corresponding Packet Kind. It contains the DHT Public Key of an addressee, and a
DHT Packet which is to be received by the addressee.

\begin{tabular}{l|l|l}
  Length             & Type        & \href{#protocol-packet}{Contents} \\
  \hline
  \texttt{32}        & Public Key  & Addressee DHT Public Key \\
  \texttt{[72,]}     & DHT Packet  & DHT Packet \\
\end{tabular}

\begin{code}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric      #-}
{-# LANGUAGE StrictData         #-}
module Network.Tox.DHT.DhtRequestPacket where

import           Data.Binary               (Binary, get, put)
import           Data.MessagePack          (MessagePack)
import           Data.Typeable             (Typeable)
import           GHC.Generics              (Generic)

import           Network.Tox.Crypto.Key    (PublicKey)
import           Network.Tox.DHT.DhtPacket (DhtPacket)

import           Test.QuickCheck.Arbitrary (Arbitrary, arbitrary)



{-------------------------------------------------------------------------------
 -
 - :: Implementation.
 -
 ------------------------------------------------------------------------------}


data DhtRequestPacket = DhtRequestPacket
  { DhtRequestPacket -> PublicKey
addresseePublicKey :: PublicKey
  , DhtRequestPacket -> DhtPacket
dhtPacket          :: DhtPacket
  }
  deriving (DhtRequestPacket -> DhtRequestPacket -> Bool
(DhtRequestPacket -> DhtRequestPacket -> Bool)
-> (DhtRequestPacket -> DhtRequestPacket -> Bool)
-> Eq DhtRequestPacket
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DhtRequestPacket -> DhtRequestPacket -> Bool
$c/= :: DhtRequestPacket -> DhtRequestPacket -> Bool
== :: DhtRequestPacket -> DhtRequestPacket -> Bool
$c== :: DhtRequestPacket -> DhtRequestPacket -> Bool
Eq, ReadPrec [DhtRequestPacket]
ReadPrec DhtRequestPacket
Int -> ReadS DhtRequestPacket
ReadS [DhtRequestPacket]
(Int -> ReadS DhtRequestPacket)
-> ReadS [DhtRequestPacket]
-> ReadPrec DhtRequestPacket
-> ReadPrec [DhtRequestPacket]
-> Read DhtRequestPacket
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DhtRequestPacket]
$creadListPrec :: ReadPrec [DhtRequestPacket]
readPrec :: ReadPrec DhtRequestPacket
$creadPrec :: ReadPrec DhtRequestPacket
readList :: ReadS [DhtRequestPacket]
$creadList :: ReadS [DhtRequestPacket]
readsPrec :: Int -> ReadS DhtRequestPacket
$creadsPrec :: Int -> ReadS DhtRequestPacket
Read, Int -> DhtRequestPacket -> ShowS
[DhtRequestPacket] -> ShowS
DhtRequestPacket -> String
(Int -> DhtRequestPacket -> ShowS)
-> (DhtRequestPacket -> String)
-> ([DhtRequestPacket] -> ShowS)
-> Show DhtRequestPacket
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DhtRequestPacket] -> ShowS
$cshowList :: [DhtRequestPacket] -> ShowS
show :: DhtRequestPacket -> String
$cshow :: DhtRequestPacket -> String
showsPrec :: Int -> DhtRequestPacket -> ShowS
$cshowsPrec :: Int -> DhtRequestPacket -> ShowS
Show, (forall x. DhtRequestPacket -> Rep DhtRequestPacket x)
-> (forall x. Rep DhtRequestPacket x -> DhtRequestPacket)
-> Generic DhtRequestPacket
forall x. Rep DhtRequestPacket x -> DhtRequestPacket
forall x. DhtRequestPacket -> Rep DhtRequestPacket x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DhtRequestPacket x -> DhtRequestPacket
$cfrom :: forall x. DhtRequestPacket -> Rep DhtRequestPacket x
Generic, Typeable)

instance MessagePack DhtRequestPacket


instance Binary DhtRequestPacket where
  put :: DhtRequestPacket -> Put
put DhtRequestPacket
packet = do
    PublicKey -> Put
forall t. Binary t => t -> Put
put (PublicKey -> Put) -> PublicKey -> Put
forall a b. (a -> b) -> a -> b
$ DhtRequestPacket -> PublicKey
addresseePublicKey DhtRequestPacket
packet
    DhtPacket -> Put
forall t. Binary t => t -> Put
put (DhtPacket -> Put) -> DhtPacket -> Put
forall a b. (a -> b) -> a -> b
$ DhtRequestPacket -> DhtPacket
dhtPacket DhtRequestPacket
packet

  get :: Get DhtRequestPacket
get =
    PublicKey -> DhtPacket -> DhtRequestPacket
DhtRequestPacket (PublicKey -> DhtPacket -> DhtRequestPacket)
-> Get PublicKey -> Get (DhtPacket -> DhtRequestPacket)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get PublicKey
forall t. Binary t => Get t
get Get (DhtPacket -> DhtRequestPacket)
-> Get DhtPacket -> Get DhtRequestPacket
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get DhtPacket
forall t. Binary t => Get t
get

{-------------------------------------------------------------------------------
 -
 - :: Tests.
 -
 ------------------------------------------------------------------------------}


instance Arbitrary DhtRequestPacket where
  arbitrary :: Gen DhtRequestPacket
arbitrary =
    PublicKey -> DhtPacket -> DhtRequestPacket
DhtRequestPacket (PublicKey -> DhtPacket -> DhtRequestPacket)
-> Gen PublicKey -> Gen (DhtPacket -> DhtRequestPacket)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen PublicKey
forall a. Arbitrary a => Gen a
arbitrary Gen (DhtPacket -> DhtRequestPacket)
-> Gen DhtPacket -> Gen DhtRequestPacket
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen DhtPacket
forall a. Arbitrary a => Gen a
arbitrary
\end{code}