summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Exchange/Status.hs
blob: 7920f2a19fed108cdd78b962e9a3c4864be42ca5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
{-# LANGUAGE TemplateHaskell   #-}
module Network.BitTorrent.Exchange.Status
       ( -- * Peer status
         PeerStatus(..)
       , choking
       , interested
       , updateStatus

         -- * Session status
       , SessionStatus(..)
       , clientStatus
       , peerStatus

         -- ** Query
       , canUpload
       , canDownload

         -- * Extra
       , inverseStatus
       , defaultUnchokeSlots
       ) where

import Control.Lens
import Data.Aeson.TH
import Data.List as L
import Data.Default

import Network.BitTorrent.Exchange.Message


-- |
data PeerStatus = PeerStatus {
    _choking    :: !Bool
  , _interested :: !Bool
  } deriving (Show, Eq)

$(makeLenses ''PeerStatus)
$(deriveJSON L.tail ''PeerStatus)

instance Default PeerStatus where
  def = PeerStatus True False

updateStatus :: StatusUpdate -> PeerStatus -> PeerStatus
updateStatus Choke         = choking    .~ True
updateStatus Unchoke       = choking    .~ False
updateStatus Interested    = interested .~ True
updateStatus NotInterested = interested .~ False

statusUpdates :: PeerStatus -> PeerStatus -> [StatusUpdate]
statusUpdates a b = undefined

-- |
data SessionStatus = SessionStatus {
    _clientStatus :: !PeerStatus
  , _peerStatus   :: !PeerStatus
  } deriving (Show, Eq)

$(makeLenses ''SessionStatus)
$(deriveJSON L.tail ''SessionStatus)

instance Default SessionStatus where
  def = SessionStatus def def

-- | Can the /client/ transfer to the /peer/?
canUpload :: SessionStatus -> Bool
canUpload SessionStatus {..}
  = _interested _peerStatus && not (_choking _clientStatus)

-- | Can the /client/ transfer from the /peer/?
canDownload :: SessionStatus -> Bool
canDownload SessionStatus {..}
  = _interested _clientStatus && not (_choking _peerStatus)

inverseStatus :: SessionStatus -> SessionStatus
inverseStatus SessionStatus {..} = SessionStatus _peerStatus _clientStatus

-- | Indicates how many peers are allowed to download from the client
-- by default.
defaultUnchokeSlots :: Int
defaultUnchokeSlots = 4