summaryrefslogtreecommitdiff
path: root/src/Remote
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-05-11 21:26:54 +0400
committerSam T <pxqr.sta@gmail.com>2013-05-11 21:26:54 +0400
commit96c554f6ab63e6e207d0c7e65d3ef1cdef7baa9c (patch)
treefd1df83b6069895c75bce8c396d6468d6c7275f5 /src/Remote
parentb2a81b581db7f328e0ec345104fb2fea1cae1296 (diff)
+ Add scheme for error, query and resp.
Diffstat (limited to 'src/Remote')
-rw-r--r--src/Remote/KRPC/Protocol.hs75
1 files changed, 68 insertions, 7 deletions
diff --git a/src/Remote/KRPC/Protocol.hs b/src/Remote/KRPC/Protocol.hs
index 0aa7e100..8f6cc442 100644
--- a/src/Remote/KRPC/Protocol.hs
+++ b/src/Remote/KRPC/Protocol.hs
@@ -11,14 +11,20 @@
11-- 11--
12-- > See http://www.bittorrent.org/beps/bep_0005.html#krpc-protocol 12-- > See http://www.bittorrent.org/beps/bep_0005.html#krpc-protocol
13-- 13--
14{-# LANGUAGE OverloadedStrings, FlexibleContexts #-} 14{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE FlexibleContexts, TypeSynonymInstances #-}
16{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
17{-# LANGUAGE DefaultSignatures #-}
15module Remote.KRPC.Protocol 18module Remote.KRPC.Protocol
16 ( 19 (
20 -- * Message
21 KMessage(..)
22
17 -- * Error 23 -- * Error
18 KError(..), errorCode, mkKError 24 , KError(..), errorCode, mkKError
19 25
20 -- * Query 26 -- * Query
21 , KQuery(..), MethodName, ParamName, kquery 27 , KQuery(queryMethod, queryParams), MethodName, ParamName, kquery
22 28
23 -- * Response 29 -- * Response
24 , KResponse(..), ValName, kresponse 30 , KResponse(..), ValName, kresponse
@@ -40,11 +46,30 @@ import Data.BEncode
40import Data.ByteString as B 46import Data.ByteString as B
41import qualified Data.ByteString.Lazy as LB 47import qualified Data.ByteString.Lazy as LB
42import Data.Map as M 48import Data.Map as M
49import Data.Set as S
43import Data.Text as T 50import Data.Text as T
44import Network.Socket hiding (recvFrom) 51import Network.Socket hiding (recvFrom)
45import Network.Socket.ByteString 52import Network.Socket.ByteString
46 53
47 54
55
56-- | Used to validate message by its scheme
57--
58-- forall m. m `validate` scheme m
59--
60class KMessage message scheme | message -> scheme where
61 -- | Get a message scheme.
62 scheme :: message -> scheme
63
64 -- | Check a message with a scheme.
65 validate :: message -> scheme -> Bool
66
67 default validate :: Eq scheme => message -> scheme -> Bool
68 validate = (==) . scheme
69 {-# INLINE validate #-}
70
71
72-- TODO document that it is and how transferred
48data KError 73data KError
49 = GenericError { errorMessage :: Text } 74 = GenericError { errorMessage :: Text }
50 | ServerError { errorMessage :: Text } 75 | ServerError { errorMessage :: Text }
@@ -65,6 +90,11 @@ instance BEncodable KError where
65 90
66 fromBEncode _ = decodingError "KError" 91 fromBEncode _ = decodingError "KError"
67 92
93instance KMessage KError ErrorCode where
94 {-# SPECIALIZE instance KMessage KError ErrorCode #-}
95 scheme = errorCode
96 {-# INLINE scheme #-}
97
68type ErrorCode = Int 98type ErrorCode = Int
69 99
70errorCode :: KError -> ErrorCode 100errorCode :: KError -> ErrorCode
@@ -72,6 +102,7 @@ errorCode (GenericError _) = 201
72errorCode (ServerError _) = 202 102errorCode (ServerError _) = 202
73errorCode (ProtocolError _) = 203 103errorCode (ProtocolError _) = 203
74errorCode (MethodUnknown _) = 204 104errorCode (MethodUnknown _) = 204
105{-# INLINE errorCode #-}
75 106
76mkKError :: ErrorCode -> Text -> KError 107mkKError :: ErrorCode -> Text -> KError
77mkKError 201 = GenericError 108mkKError 201 = GenericError
@@ -79,15 +110,20 @@ mkKError 202 = ServerError
79mkKError 203 = ProtocolError 110mkKError 203 = ProtocolError
80mkKError 204 = MethodUnknown 111mkKError 204 = MethodUnknown
81mkKError _ = GenericError 112mkKError _ = GenericError
113{-# INLINE mkKError #-}
114
82 115
83 116
117-- TODO Asc everywhere
118
84 119
85type MethodName = ByteString 120type MethodName = ByteString
86type ParamName = ByteString 121type ParamName = ByteString
87 122
123-- TODO document that it is and how transferred
88data KQuery = KQuery { 124data KQuery = KQuery {
89 queryMethod :: MethodName 125 queryMethod :: MethodName
90 , queryArgs :: Map ParamName BEncode 126 , queryParams :: Map ParamName BEncode
91 } deriving (Show, Read, Eq, Ord) 127 } deriving (Show, Read, Eq, Ord)
92 128
93instance BEncodable KQuery where 129instance BEncodable KQuery where
@@ -106,14 +142,27 @@ instance BEncodable KQuery where
106 142
107kquery :: MethodName -> [(ParamName, BEncode)] -> KQuery 143kquery :: MethodName -> [(ParamName, BEncode)] -> KQuery
108kquery name args = KQuery name (M.fromList args) 144kquery name args = KQuery name (M.fromList args)
145{-# INLINE kquery #-}
109 146
147data KQueryScheme = KQueryScheme {
148 qscMethod :: MethodName
149 , qscParams :: Set ParamName
150 } deriving (Show, Read, Eq, Ord)
110 151
152domen :: Map a b -> Set a
153domen = error "scheme.domen"
111 154
155instance KMessage KQuery KQueryScheme where
156 {-# SPECIALIZE instance KMessage KQuery KQueryScheme #-}
157 scheme q = KQueryScheme (queryMethod q) (domen (queryParams q))
158 {-# INLINE scheme #-}
112 159
113type ValName = ByteString 160type ValName = ByteString
114 161
115newtype KResponse = KResponse (Map ValName BEncode) 162-- TODO document that it is and how transferred
116 deriving (Show, Read, Eq, Ord) 163newtype KResponse = KResponse {
164 respVals :: Map ValName BEncode
165 } deriving (Show, Read, Eq, Ord)
117 166
118instance BEncodable KResponse where 167instance BEncodable KResponse where
119 toBEncode (KResponse vals) = fromAssocs 168 toBEncode (KResponse vals) = fromAssocs
@@ -121,21 +170,33 @@ instance BEncodable KResponse where
121 , "r" --> vals 170 , "r" --> vals
122 ] 171 ]
123 172
124
125 fromBEncode (BDict d) 173 fromBEncode (BDict d)
126 | M.lookup "y" d == Just (BString "r") = 174 | M.lookup "y" d == Just (BString "r") =
127 KResponse <$> d >-- "r" 175 KResponse <$> d >-- "r"
128 176
129 fromBEncode _ = decodingError "KDict" 177 fromBEncode _ = decodingError "KDict"
130 178
179
131kresponse :: [(ValName, BEncode)] -> KResponse 180kresponse :: [(ValName, BEncode)] -> KResponse
132kresponse = KResponse . M.fromList 181kresponse = KResponse . M.fromList
182{-# INLINE kresponse #-}
183
184newtype KResponseScheme = KResponseScheme {
185 rscVals :: Set ValName
186 } deriving (Show, Read, Eq, Ord)
187
188instance KMessage KResponse KResponseScheme where
189 {-# SPECIALIZE instance KMessage KResponse KResponseScheme #-}
190 scheme = KResponseScheme . domen . respVals
191 {-# INLINE scheme #-}
133 192
134 193
135type KRemoteAddr = (HostAddress, PortNumber) 194type KRemoteAddr = (HostAddress, PortNumber)
136 195
137remoteAddr :: KRemoteAddr -> SockAddr 196remoteAddr :: KRemoteAddr -> SockAddr
138remoteAddr = SockAddrInet <$> snd <*> fst 197remoteAddr = SockAddrInet <$> snd <*> fst
198{-# INLINE remoteAddr #-}
199
139 200
140type KRemote = Socket 201type KRemote = Socket
141 202