torrust_tracker/servers/http/v1/responses/error.rs
1//! `Error` response for the [`HTTP tracker`](crate::servers::http).
2//!
3//! Data structures and logic to build the error responses.
4//!
5//! From the [BEP 03. The `BitTorrent` Protocol Specification](https://www.bittorrent.org/beps/bep_0003.html):
6//!
7//! _"Tracker responses are bencoded dictionaries. If a tracker response has a
8//! key failure reason, then that maps to a human readable string which explains
9//! why the query failed, and no other keys are required."_
10//!
11//! > **NOTICE**: error responses are bencoded and always have a `200 OK` status
12//! > code. The official `BitTorrent` specification does not specify the status
13//! > code.
14use axum::http::StatusCode;
15use axum::response::{IntoResponse, Response};
16use serde::Serialize;
17
18/// `Error` response for the [`HTTP tracker`](crate::servers::http).
19#[derive(Serialize, Debug, PartialEq)]
20pub struct Error {
21 /// Human readable string which explains why the request failed.
22 #[serde(rename = "failure reason")]
23 pub failure_reason: String,
24}
25
26impl Error {
27 /// Returns the bencoded representation of the `Error` struct.
28 ///
29 /// ```rust
30 /// use torrust_tracker::servers::http::v1::responses::error::Error;
31 ///
32 /// let err = Error {
33 /// failure_reason: "error message".to_owned(),
34 /// };
35 ///
36 /// // cspell:disable-next-line
37 /// assert_eq!(err.write(), "d14:failure reason13:error messagee");
38 /// ```
39 ///
40 /// # Panics
41 ///
42 /// It would panic if the `Error` struct contained an inappropriate field
43 /// type.
44 #[must_use]
45 pub fn write(&self) -> String {
46 serde_bencode::to_string(&self).unwrap()
47 }
48}
49
50impl IntoResponse for Error {
51 fn into_response(self) -> Response {
52 (StatusCode::OK, self.write()).into_response()
53 }
54}
55
56#[cfg(test)]
57mod tests {
58
59 use super::Error;
60
61 #[test]
62 fn http_tracker_errors_can_be_bencoded() {
63 let err = Error {
64 failure_reason: "error message".to_owned(),
65 };
66
67 assert_eq!(err.write(), "d14:failure reason13:error messagee"); // cspell:disable-line
68 }
69}