Skip to content

Commit

Permalink
refactor: [#639] UDP client. Extract aquatic reponses wrappers
Browse files Browse the repository at this point in the history
for serialization to JSON.
  • Loading branch information
josecelano committed Feb 1, 2024
1 parent a2e123c commit 1b92b77
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 40 deletions.
65 changes: 25 additions & 40 deletions src/console/clients/udp/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ use aquatic_udp_protocol::Response::{self, AnnounceIpv4, AnnounceIpv6, Scrape};
use aquatic_udp_protocol::{Port, TransactionId};
use clap::{Parser, Subcommand};
use log::{debug, LevelFilter};
use serde_json::json;
use url::Url;

use crate::console::clients::udp::checker;
use crate::console::clients::udp::responses::{AnnounceResponseDto, ScrapeResponseDto};
use crate::shared::bit_torrent::info_hash::InfoHash as TorrustInfoHash;

const ASSIGNED_BY_OS: u16 = 0;
Expand Down Expand Up @@ -117,45 +117,7 @@ pub async fn run() -> anyhow::Result<()> {
} => handle_scrape(&tracker_socket_addr, &info_hashes).await?,
};

match response {
AnnounceIpv4(announce) => {
let json = json!({
"transaction_id": announce.transaction_id.0,
"announce_interval": announce.announce_interval.0,
"leechers": announce.leechers.0,
"seeders": announce.seeders.0,
"peers": announce.peers.iter().map(|peer| format!("{}:{}", peer.ip_address, peer.port.0)).collect::<Vec<_>>(),
});
let pretty_json = serde_json::to_string_pretty(&json).context("announce IPv4 response JSON serialization")?;
println!("{pretty_json}");
}
AnnounceIpv6(announce) => {
let json = json!({
"transaction_id": announce.transaction_id.0,
"announce_interval": announce.announce_interval.0,
"leechers": announce.leechers.0,
"seeders": announce.seeders.0,
"peers6": announce.peers.iter().map(|peer| format!("{}:{}", peer.ip_address, peer.port.0)).collect::<Vec<_>>(),
});
let pretty_json = serde_json::to_string_pretty(&json).context("announce IPv6 response JSON serialization")?;
println!("{pretty_json}");
}
Scrape(scrape) => {
let json = json!({
"transaction_id": scrape.transaction_id.0,
"torrent_stats": scrape.torrent_stats.iter().map(|torrent_scrape_statistics| json!({
"seeders": torrent_scrape_statistics.seeders.0,
"completed": torrent_scrape_statistics.completed.0,
"leechers": torrent_scrape_statistics.leechers.0,
})).collect::<Vec<_>>(),
});
let pretty_json = serde_json::to_string_pretty(&json).context("scrape response JSON serialization")?;
println!("{pretty_json}");
}
_ => println!("{response:#?}"), // todo: serialize to JSON all responses.
};

Ok(())
print_response(response)
}

fn setup_logging(level: LevelFilter) {
Expand Down Expand Up @@ -207,6 +169,29 @@ async fn handle_scrape(tracker_socket_addr: &SocketAddr, info_hashes: &[TorrustI
.await
}

Check warning on line 170 in src/console/clients/udp/app.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/app.rs#L170

Added line #L170 was not covered by tests

fn print_response(response: Response) -> anyhow::Result<()> {
match response {
AnnounceIpv4(response) => {
let pretty_json = serde_json::to_string_pretty(&AnnounceResponseDto::from(response))
.context("announce IPv4 response JSON serialization")?;
println!("{pretty_json}");
}
AnnounceIpv6(response) => {
let pretty_json = serde_json::to_string_pretty(&AnnounceResponseDto::from(response))
.context("announce IPv6 response JSON serialization")?;
println!("{pretty_json}");
}
Scrape(response) => {
let pretty_json =
serde_json::to_string_pretty(&ScrapeResponseDto::from(response)).context("scrape response JSON serialization")?;
println!("{pretty_json}");
}
_ => println!("{response:#?}"), // todo: serialize to JSON all aquatic responses.

Check warning on line 189 in src/console/clients/udp/app.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/app.rs#L172-L189

Added lines #L172 - L189 were not covered by tests
};

Ok(())
}

Check warning on line 193 in src/console/clients/udp/app.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/app.rs#L192-L193

Added lines #L192 - L193 were not covered by tests

fn parse_socket_addr(tracker_socket_addr_str: &str) -> anyhow::Result<SocketAddr> {
debug!("Tracker socket address: {tracker_socket_addr_str:#?}");

Expand Down
1 change: 1 addition & 0 deletions src/console/clients/udp/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod app;
pub mod checker;
pub mod responses;
83 changes: 83 additions & 0 deletions src/console/clients/udp/responses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! Aquatic responses are not serializable. These are the serializable wrappers.
use std::net::{Ipv4Addr, Ipv6Addr};

use aquatic_udp_protocol::{AnnounceResponse, ScrapeResponse};
use serde::Serialize;

#[derive(Serialize)]

Check warning on line 7 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L7

Added line #L7 was not covered by tests
pub struct AnnounceResponseDto {
transaction_id: i32,
announce_interval: i32,
leechers: i32,
seeders: i32,
peers: Vec<String>,
}

impl From<AnnounceResponse<Ipv4Addr>> for AnnounceResponseDto {
fn from(announce: AnnounceResponse<Ipv4Addr>) -> Self {
Self {
transaction_id: announce.transaction_id.0,
announce_interval: announce.announce_interval.0,
leechers: announce.leechers.0,
seeders: announce.seeders.0,
peers: announce

Check warning on line 23 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L17-L23

Added lines #L17 - L23 were not covered by tests
.peers
.iter()
.map(|peer| format!("{}:{}", peer.ip_address, peer.port.0))

Check warning on line 26 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L26

Added line #L26 was not covered by tests
.collect::<Vec<_>>(),
}
}

Check warning on line 29 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L28-L29

Added lines #L28 - L29 were not covered by tests
}

impl From<AnnounceResponse<Ipv6Addr>> for AnnounceResponseDto {
fn from(announce: AnnounceResponse<Ipv6Addr>) -> Self {
Self {
transaction_id: announce.transaction_id.0,
announce_interval: announce.announce_interval.0,
leechers: announce.leechers.0,
seeders: announce.seeders.0,
peers: announce

Check warning on line 39 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L33-L39

Added lines #L33 - L39 were not covered by tests
.peers
.iter()
.map(|peer| format!("{}:{}", peer.ip_address, peer.port.0))

Check warning on line 42 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L42

Added line #L42 was not covered by tests
.collect::<Vec<_>>(),
}
}

Check warning on line 45 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L44-L45

Added lines #L44 - L45 were not covered by tests
}

#[derive(Serialize)]

Check warning on line 48 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L48

Added line #L48 was not covered by tests
pub struct ScrapeResponseDto {
transaction_id: i32,
torrent_stats: Vec<TorrentStats>,
}

impl From<ScrapeResponse> for ScrapeResponseDto {
fn from(scrape: ScrapeResponse) -> Self {
Self {
transaction_id: scrape.transaction_id.0,
torrent_stats: scrape

Check warning on line 58 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L55-L58

Added lines #L55 - L58 were not covered by tests
.torrent_stats
.iter()
.map(|torrent_scrape_statistics| TorrentStats {
seeders: torrent_scrape_statistics.seeders.0,
completed: torrent_scrape_statistics.completed.0,
leechers: torrent_scrape_statistics.leechers.0,
})

Check warning on line 65 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L61-L65

Added lines #L61 - L65 were not covered by tests
.collect::<Vec<_>>(),
}
}

Check warning on line 68 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L67-L68

Added lines #L67 - L68 were not covered by tests
}

#[derive(Serialize)]
struct Peer {
seeders: i32,
completed: i32,
leechers: i32,
}

#[derive(Serialize)]

Check warning on line 78 in src/console/clients/udp/responses.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/responses.rs#L78

Added line #L78 was not covered by tests
struct TorrentStats {
seeders: i32,
completed: i32,
leechers: i32,
}

0 comments on commit 1b92b77

Please sign in to comment.