1use crate::api::Api;
2use crate::data::*;
3use crate::error::Result;
4use async_trait::async_trait;
5use std::collections::HashMap;
6
7#[async_trait]
8pub trait TorrentsApi {
9 fn hashes(&self) -> String;
10
11 async fn stop(&self, api: &Api) -> Result<()> {
12 let mut form = HashMap::new();
13 form.insert("hashes", self.hashes());
14 api.post_status("/api/v2/torrents/stop", &form).await
15 }
16
17 async fn start(&self, api: &Api) -> Result<()> {
18 let mut form = HashMap::new();
19 form.insert("hashes", self.hashes());
20 api.post_status("/api/v2/torrents/start", &form).await
21 }
22
23 async fn delete(&self, api: &Api, delete_data: bool) -> Result<()> {
24 let mut form = HashMap::new();
25 form.insert("hashes", self.hashes());
26 form.insert(
27 "deleteFiles",
28 if delete_data { "true" } else { "false" }.into(),
29 );
30 api.post_status("/api/v2/torrents/delete", &form).await
31 }
32
33 async fn recheck(&self, api: &Api) -> Result<()> {
34 let mut form = HashMap::new();
35 form.insert("hashes", self.hashes());
36 api.post_status("/api/v2/torrents/recheck", &form).await
37 }
38
39 async fn set_category(&self, api: &Api, category: &str) -> Result<()> {
40 let mut form = HashMap::new();
41 form.insert("hashes", self.hashes());
42 form.insert("category", category.into());
43 api.post_status("/api/v2/torrents/setCategory", &form).await
44 }
45
46 async fn add_tags(&self, api: &Api, tags: &[String]) -> Result<()> {
47 let mut form = HashMap::new();
48 form.insert("hashes", self.hashes());
49 form.insert("tags", tags.join(","));
50 api.post_status("/api/v2/torrents/addTags", &form).await
51 }
52
53 async fn remove_tags(&self, api: &Api, tags: &[String]) -> Result<()> {
54 let mut form = HashMap::new();
55 form.insert("hashes", self.hashes());
56 form.insert("tags", tags.join(","));
57 api.post_status("/api/v2/torrents/removeTags", &form).await
58 }
59
60 async fn bottom_priority(&self, api: &Api) -> Result<()> {
61 let mut form = HashMap::new();
62 form.insert("hashes", self.hashes());
63 api.post_status("/api/v2/torrents/bottomPrio", &form).await
64 }
65
66 async fn top_priority(&self, api: &Api) -> Result<()> {
67 let mut form = HashMap::new();
68 form.insert("hashes", self.hashes());
69 api.post_status("/api/v2/torrents/topPrio", &form).await
70 }
71}
72
73impl TorrentsApi for Torrent {
74 fn hashes(&self) -> String {
75 self.hash.hash.clone()
76 }
77}
78
79impl TorrentsApi for [Torrent] {
80 fn hashes(&self) -> String {
81 let refs: Vec<&str> = self.iter().map(|h| h.hash.as_str()).collect();
82 refs.join("|")
83 }
84}
85
86impl TorrentsApi for Vec<Torrent> {
87 fn hashes(&self) -> String {
88 let refs: Vec<&str> = self.iter().map(|h| h.hash.as_str()).collect();
89 refs.join("|")
90 }
91}
92
93impl TorrentsApi for Hash {
94 fn hashes(&self) -> String {
95 self.hash.clone()
96 }
97}
98
99impl TorrentsApi for [Hash] {
100 fn hashes(&self) -> String {
101 let refs: Vec<&str> = self.iter().map(|h| h.hash.as_str()).collect();
102 refs.join("|")
103 }
104}
105
106impl TorrentsApi for Vec<Hash> {
107 fn hashes(&self) -> String {
108 let refs: Vec<&str> = self.iter().map(|h| h.hash.as_str()).collect();
109 refs.join("|")
110 }
111}
112
113#[async_trait]
114pub trait TorrentApi {
115 fn hash(&self) -> String;
116
117 async fn properties(&self, api: &Api) -> Result<TorrentProperties> {
118 let mut form = HashMap::new();
119 form.insert("hash", self.hash());
120 api.post_decode("/api/v2/torrents/properties", &form).await
121 }
122
123 async fn trackers(&self, api: &Api) -> Result<Vec<Tracker>> {
124 let mut form = HashMap::new();
125 form.insert("hash", self.hash());
126 api.post_decode("/api/v2/torrents/trackers", &form).await
127 }
128
129 async fn contents(&self, api: &Api) -> Result<Vec<TorrentInfo>> {
130 let mut form = HashMap::new();
131 form.insert("hash", self.hash());
132 api.post_decode("/api/v2/torrents/files", &form).await
133 }
134}
135
136impl TorrentApi for Torrent {
137 fn hash(&self) -> String {
138 self.hash.hash.clone()
139 }
140}
141
142impl TorrentApi for Hash {
143 fn hash(&self) -> String {
144 self.hash.clone()
145 }
146}