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

View file

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

View file

@ -52,4 +52,26 @@ pub enum Request {
Announce(AnnounceRequest), Announce(AnnounceRequest),
Scrape(ScrapeRequest), Scrape(ScrapeRequest),
Invalid(InvalidRequest), 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)] #[cfg(test)]
impl quickcheck::Arbitrary for TorrentScrapeStatistics { impl quickcheck::Arbitrary for TorrentScrapeStatistics {
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self { fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {