bittorrent_udp: add From<> for requests and responses into their enums

This commit is contained in:
Joakim Frostegård 2020-04-10 11:19:29 +02:00
parent 44b0489521
commit f80646e3a8
4 changed files with 69 additions and 19 deletions

View file

@ -78,9 +78,9 @@ pub fn request_from_bytes(
// Connect
0 => {
if connection_id == PROTOCOL_IDENTIFIER {
Ok(Request::Connect(ConnectRequest {
Ok((ConnectRequest {
transaction_id: TransactionId(transaction_id)
}))
}).into())
} else {
Ok(Request::Invalid(InvalidRequest {
transaction_id: TransactionId(transaction_id),
@ -117,7 +117,7 @@ pub fn request_from_bytes(
Some(Ipv4Addr::from(ip))
};
Ok(Request::Announce(AnnounceRequest {
Ok((AnnounceRequest {
connection_id: ConnectionId(connection_id),
transaction_id: TransactionId(transaction_id),
info_hash: InfoHash(info_hash),
@ -130,7 +130,7 @@ pub fn request_from_bytes(
key: PeerKey(key),
peers_wanted: NumberOfPeers(peers_wanted),
port: Port(port)
}))
}).into())
},
// Scrape
@ -143,11 +143,11 @@ pub fn request_from_bytes(
.map(|chunk| InfoHash(chunk.try_into().unwrap()))
.collect();
Ok(Request::Scrape(ScrapeRequest {
Ok((ScrapeRequest {
connection_id: ConnectionId(connection_id),
transaction_id: TransactionId(transaction_id),
info_hashes
}))
}).into())
}
_ => Ok(Request::Invalid(InvalidRequest {

View file

@ -85,10 +85,10 @@ pub fn response_from_bytes(
0 => {
let connection_id = cursor.read_i64::<NetworkEndian>()?;
Ok(Response::Connect(ConnectResponse {
Ok((ConnectResponse {
connection_id: ConnectionId(connection_id),
transaction_id: TransactionId(transaction_id)
}))
}).into())
},
// Announce
1 => {
@ -123,13 +123,13 @@ pub fn response_from_bytes(
}).collect()
};
Ok(Response::Announce(AnnounceResponse {
Ok((AnnounceResponse {
transaction_id: TransactionId(transaction_id),
announce_interval: AnnounceInterval(announce_interval),
leechers: NumberOfPeers(leechers),
seeders: NumberOfPeers(seeders),
peers
}))
}).into())
},
// Scrape
@ -151,26 +151,26 @@ pub fn response_from_bytes(
}
}).collect();
Ok(Response::Scrape(ScrapeResponse {
Ok((ScrapeResponse {
transaction_id: TransactionId(transaction_id),
torrent_stats: stats
}))
}).into())
},
// Error
3 => {
let position = cursor.position() as usize;
let inner = cursor.into_inner();
Ok(Response::Error(ErrorResponse {
Ok((ErrorResponse {
transaction_id: TransactionId(transaction_id),
message: String::from_utf8_lossy(&inner[position..]).into()
}))
}).into())
},
_ => {
Ok(Response::Error(ErrorResponse {
Ok((ErrorResponse {
transaction_id: TransactionId(transaction_id),
message: "Invalid action".to_string()
}))
}).into())
}
}
}
@ -200,7 +200,7 @@ mod tests {
#[test]
fn test_convert_identity_connect_response(){
fn prop(response: ConnectResponse) -> TestResult {
TestResult::from_bool(same_after_conversion(Response::Connect(response), IpVersion::IPv4))
TestResult::from_bool(same_after_conversion(response.into(), IpVersion::IPv4))
}
quickcheck(prop as fn(ConnectResponse) -> TestResult);
@ -217,7 +217,7 @@ mod tests {
r.peers.retain(|peer| peer.ip_address.is_ipv6());
}
TestResult::from_bool(same_after_conversion(Response::Announce(r), data.1))
TestResult::from_bool(same_after_conversion(r.into(), data.1))
}
quickcheck(prop as fn((AnnounceResponse, IpVersion)) -> TestResult);
@ -226,7 +226,7 @@ mod tests {
#[test]
fn test_convert_identity_scrape_response(){
fn prop(response: ScrapeResponse) -> TestResult {
TestResult::from_bool(same_after_conversion(Response::Scrape(response), IpVersion::IPv4))
TestResult::from_bool(same_after_conversion(response.into(), IpVersion::IPv4))
}
quickcheck(prop as fn(ScrapeResponse) -> TestResult);

View file

@ -52,4 +52,26 @@ pub enum Request {
Announce(AnnounceRequest),
Scrape(ScrapeRequest),
Invalid(InvalidRequest),
}
impl From<ConnectRequest> for Request {
fn from(r: ConnectRequest) -> Self {
Self::Connect(r)
}
}
impl From<AnnounceRequest> for Request {
fn from(r: AnnounceRequest) -> Self {
Self::Announce(r)
}
}
impl From<ScrapeRequest> for Request {
fn from(r: ScrapeRequest) -> Self {
Self::Scrape(r)
}
}

View file

@ -45,6 +45,34 @@ pub enum Response {
}
impl From<ConnectResponse> for Response {
fn from(r: ConnectResponse) -> Self {
Self::Connect(r)
}
}
impl From<AnnounceResponse> for Response {
fn from(r: AnnounceResponse) -> Self {
Self::Announce(r)
}
}
impl From<ScrapeResponse> for Response {
fn from(r: ScrapeResponse) -> Self {
Self::Scrape(r)
}
}
impl From<ErrorResponse> for Response {
fn from(r: ErrorResponse) -> Self {
Self::Error(r)
}
}
#[cfg(test)]
impl quickcheck::Arbitrary for TorrentScrapeStatistics {
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {