torrust_tracker/console/clients/udp/responses/
dto.rs

1//! Aquatic responses are not serializable. These are the serializable wrappers.
2use std::net::{Ipv4Addr, Ipv6Addr};
3
4use aquatic_udp_protocol::Response::{self};
5use aquatic_udp_protocol::{AnnounceResponse, ConnectResponse, ErrorResponse, Ipv4AddrBytes, Ipv6AddrBytes, ScrapeResponse};
6use serde::Serialize;
7
8#[derive(Serialize)]
9pub enum SerializableResponse {
10    Connect(ConnectSerializableResponse),
11    AnnounceIpv4(AnnounceSerializableResponse),
12    AnnounceIpv6(AnnounceSerializableResponse),
13    Scrape(ScrapeSerializableResponse),
14    Error(ErrorSerializableResponse),
15}
16
17impl From<Response> for SerializableResponse {
18    fn from(response: Response) -> Self {
19        match response {
20            Response::Connect(response) => SerializableResponse::Connect(ConnectSerializableResponse::from(response)),
21            Response::AnnounceIpv4(response) => SerializableResponse::AnnounceIpv4(AnnounceSerializableResponse::from(response)),
22            Response::AnnounceIpv6(response) => SerializableResponse::AnnounceIpv6(AnnounceSerializableResponse::from(response)),
23            Response::Scrape(response) => SerializableResponse::Scrape(ScrapeSerializableResponse::from(response)),
24            Response::Error(response) => SerializableResponse::Error(ErrorSerializableResponse::from(response)),
25        }
26    }
27}
28
29#[derive(Serialize)]
30pub struct ConnectSerializableResponse {
31    transaction_id: i32,
32    connection_id: i64,
33}
34
35impl From<ConnectResponse> for ConnectSerializableResponse {
36    fn from(connect: ConnectResponse) -> Self {
37        Self {
38            transaction_id: connect.transaction_id.0.into(),
39            connection_id: connect.connection_id.0.into(),
40        }
41    }
42}
43
44#[derive(Serialize)]
45pub struct AnnounceSerializableResponse {
46    transaction_id: i32,
47    announce_interval: i32,
48    leechers: i32,
49    seeders: i32,
50    peers: Vec<String>,
51}
52
53impl From<AnnounceResponse<Ipv4AddrBytes>> for AnnounceSerializableResponse {
54    fn from(announce: AnnounceResponse<Ipv4AddrBytes>) -> Self {
55        Self {
56            transaction_id: announce.fixed.transaction_id.0.into(),
57            announce_interval: announce.fixed.announce_interval.0.into(),
58            leechers: announce.fixed.leechers.0.into(),
59            seeders: announce.fixed.seeders.0.into(),
60            peers: announce
61                .peers
62                .iter()
63                .map(|peer| format!("{}:{}", Ipv4Addr::from(peer.ip_address), peer.port.0))
64                .collect::<Vec<_>>(),
65        }
66    }
67}
68
69impl From<AnnounceResponse<Ipv6AddrBytes>> for AnnounceSerializableResponse {
70    fn from(announce: AnnounceResponse<Ipv6AddrBytes>) -> Self {
71        Self {
72            transaction_id: announce.fixed.transaction_id.0.into(),
73            announce_interval: announce.fixed.announce_interval.0.into(),
74            leechers: announce.fixed.leechers.0.into(),
75            seeders: announce.fixed.seeders.0.into(),
76            peers: announce
77                .peers
78                .iter()
79                .map(|peer| format!("{}:{}", Ipv6Addr::from(peer.ip_address), peer.port.0))
80                .collect::<Vec<_>>(),
81        }
82    }
83}
84
85#[derive(Serialize)]
86pub struct ScrapeSerializableResponse {
87    transaction_id: i32,
88    torrent_stats: Vec<TorrentStats>,
89}
90
91impl From<ScrapeResponse> for ScrapeSerializableResponse {
92    fn from(scrape: ScrapeResponse) -> Self {
93        Self {
94            transaction_id: scrape.transaction_id.0.into(),
95            torrent_stats: scrape
96                .torrent_stats
97                .iter()
98                .map(|torrent_scrape_statistics| TorrentStats {
99                    seeders: torrent_scrape_statistics.seeders.0.into(),
100                    completed: torrent_scrape_statistics.completed.0.into(),
101                    leechers: torrent_scrape_statistics.leechers.0.into(),
102                })
103                .collect::<Vec<_>>(),
104        }
105    }
106}
107
108#[derive(Serialize)]
109pub struct ErrorSerializableResponse {
110    transaction_id: i32,
111    message: String,
112}
113
114impl From<ErrorResponse> for ErrorSerializableResponse {
115    fn from(error: ErrorResponse) -> Self {
116        Self {
117            transaction_id: error.transaction_id.0.into(),
118            message: error.message.to_string(),
119        }
120    }
121}
122
123#[derive(Serialize)]
124struct TorrentStats {
125    seeders: i32,
126    completed: i32,
127    leechers: i32,
128}