qb_api/
traits.rs

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}