From fe596672eaf47e24c18b7d8f61d5453defa6e54a Mon Sep 17 00:00:00 2001 From: Artem Vorotnikov Date: Wed, 7 Sep 2022 00:58:00 +0300 Subject: [PATCH] Edition 2021, rustfmt, clippy, better CI --- .github/workflows/ci.yml | 52 +++++++++++-------- Cargo.toml | 12 ++--- examples/blocklist-update.rs | 4 +- examples/free-space.rs | 6 +-- examples/port-test.rs | 6 +-- examples/session-close.rs | 4 +- examples/session-get.rs | 4 +- examples/session-stats.rs | 4 +- examples/torrent-action.rs | 13 +++-- examples/torrent-add.rs | 10 ++-- examples/torrent-get.rs | 37 ++++++++++---- examples/torrent-remove.rs | 5 +- examples/torrent-rename-path.rs | 20 +++++--- examples/torrent-set-location.rs | 11 ++-- src/lib.rs | 88 ++++++++++++++++---------------- src/types/mod.rs | 25 +++------ src/types/request.rs | 77 ++++++++++++---------------- src/types/response.rs | 5 +- 18 files changed, 200 insertions(+), 183 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e88cd2c..4e0f1e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ name: CI -on: +on: push: pull_request: branches: @@ -13,41 +13,49 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get Rust uses: actions-rs/toolchain@v1 with: + profile: minimal toolchain: stable + components: rustfmt, clippy - name: Setup Test Enviroment run: docker-compose up -d - - name: Use Cache - uses: actions/cache@v2 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - - name: Cargo Build + - name: Check formatting uses: actions-rs/cargo@v1 with: - command: build - args: --release --all-features + command: fmt + args: --all -- --check + + - name: Cargo check + uses: actions-rs/cargo@v1 + with: + command: check + args: --workspace --all-targets --all-features - name: Cargo Test - uses: actions-rs/toolchain@v1 + uses: actions-rs/cargo@v1 with: - toolchain: stable - - run: cargo test -- --skip session_close + command: test + args: -- --skip session_close - name: Cargo Test Session Close - uses: actions-rs/toolchain@v1 + uses: actions-rs/cargo@v1 with: - toolchain: stable - - run: cargo test -- session_close + command: test + args: -- session_close + + - name: Cargo clippy + uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + args: --all-features + + - name: Cargo audit + uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.toml b/Cargo.toml index c069bce..03be7f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,20 +2,20 @@ name = "transmission-rpc" version = "0.3.6" authors = ["red "] -edition = "2018" +edition = "2021" repository = "https://github.com/j0rsa/transmission-rpc" license = "MIT" readme = "README.md" description = "Transmission JRPC client" keywords = ["transmission", "torrent", "jrpc"] categories = ["api-bindings"] -include = [ - "**/*.rs", - "Cargo.toml", -] +include = ["**/*.rs", "Cargo.toml"] [dependencies] -reqwest = { version = "0.11.2", features = ["json", "rustls-tls"], default-features = false } +reqwest = { version = "0.11.2", features = [ + "json", + "rustls-tls", +], default-features = false } serde = { version = "1.0.124", features = ["derive"] } enum-iterator = "0.8.1" diff --git a/examples/blocklist-update.rs b/examples/blocklist-update.rs index 078a079..1f93617 100644 --- a/examples/blocklist-update.rs +++ b/examples/blocklist-update.rs @@ -12,14 +12,14 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } let response: Result> = client.blocklist_update().await; match response { Ok(_) => println!("Yay!"), - Err(_) => panic!("Oh no!") + Err(_) => panic!("Oh no!"), } println!("Rpc response is ok: {}", response?.is_ok()); Ok(()) diff --git a/examples/free-space.rs b/examples/free-space.rs index 0df5fc3..fe36b7b 100644 --- a/examples/free-space.rs +++ b/examples/free-space.rs @@ -2,7 +2,7 @@ extern crate transmission_rpc; use dotenv::dotenv; use std::env; -use transmission_rpc::types::{BasicAuth, Result, RpcResponse, FreeSpace}; +use transmission_rpc::types::{BasicAuth, FreeSpace, Result, RpcResponse}; use transmission_rpc::TransClient; #[tokio::main] @@ -13,14 +13,14 @@ async fn main() -> Result<()> { let dir = env::var("TDIR")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } let response: Result> = client.free_space(dir).await; match response { Ok(_) => println!("Yay!"), - Err(_) => panic!("Oh no!") + Err(_) => panic!("Oh no!"), } println!("Rpc response is ok: {}", response?.is_ok()); Ok(()) diff --git a/examples/port-test.rs b/examples/port-test.rs index b4a2da5..fc03210 100644 --- a/examples/port-test.rs +++ b/examples/port-test.rs @@ -2,7 +2,7 @@ extern crate transmission_rpc; use dotenv::dotenv; use std::env; -use transmission_rpc::types::{BasicAuth, Result, RpcResponse, PortTest}; +use transmission_rpc::types::{BasicAuth, PortTest, Result, RpcResponse}; use transmission_rpc::TransClient; #[tokio::main] @@ -12,14 +12,14 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } let response: Result> = client.port_test().await; match response { Ok(_) => println!("Yay!"), - Err(_) => panic!("Oh no!") + Err(_) => panic!("Oh no!"), } println!("Rpc response is ok: {}", response?.is_ok()); Ok(()) diff --git a/examples/session-close.rs b/examples/session-close.rs index 82776ea..ab834d7 100644 --- a/examples/session-close.rs +++ b/examples/session-close.rs @@ -12,14 +12,14 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } let response: Result> = client.session_close().await; match response { Ok(_) => println!("Yay!"), - Err(_) => panic!("Oh no!") + Err(_) => panic!("Oh no!"), } println!("Rpc response is ok: {}", response?.is_ok()); Ok(()) diff --git a/examples/session-get.rs b/examples/session-get.rs index 9dbeaa6..90e94e1 100644 --- a/examples/session-get.rs +++ b/examples/session-get.rs @@ -12,14 +12,14 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } let response: Result> = client.session_get().await; match response { Ok(_) => println!("Yay!"), - Err(_) => panic!("Oh no!") + Err(_) => panic!("Oh no!"), } println!("Rpc response is ok: {}", response?.is_ok()); Ok(()) diff --git a/examples/session-stats.rs b/examples/session-stats.rs index a4c4a17..b2d8ec3 100644 --- a/examples/session-stats.rs +++ b/examples/session-stats.rs @@ -12,14 +12,14 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } let response: Result> = client.session_stats().await; match response { Ok(_) => println!("Yay!"), - Err(_) => panic!("Oh no!") + Err(_) => panic!("Oh no!"), } println!("Rpc response is ok: {}", response?.is_ok()); Ok(()) diff --git a/examples/torrent-action.rs b/examples/torrent-action.rs index 855082c..fd37041 100644 --- a/examples/torrent-action.rs +++ b/examples/torrent-action.rs @@ -2,8 +2,7 @@ extern crate transmission_rpc; use dotenv::dotenv; use std::env; -use transmission_rpc::types::{BasicAuth, Result, RpcResponse}; -use transmission_rpc::types::{Id, Nothing, TorrentAction}; +use transmission_rpc::types::{BasicAuth, Id, Nothing, Result, RpcResponse, TorrentAction}; use transmission_rpc::TransClient; #[tokio::main] @@ -13,13 +12,17 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } - let res1: RpcResponse = client.torrent_action(TorrentAction::Start, vec![Id::Id(1)]).await?; + let res1: RpcResponse = client + .torrent_action(TorrentAction::Start, vec![Id::Id(1)]) + .await?; println!("Start result: {:?}", &res1.is_ok()); - let res2: RpcResponse = client.torrent_action(TorrentAction::Stop, vec![Id::Id(1)]).await?; + let res2: RpcResponse = client + .torrent_action(TorrentAction::Stop, vec![Id::Id(1)]) + .await?; println!("Stop result: {:?}", &res2.is_ok()); Ok(()) diff --git a/examples/torrent-add.rs b/examples/torrent-add.rs index 076a89e..758d4e4 100644 --- a/examples/torrent-add.rs +++ b/examples/torrent-add.rs @@ -2,8 +2,7 @@ extern crate transmission_rpc; use dotenv::dotenv; use std::env; -use transmission_rpc::types::{BasicAuth, Result, RpcResponse}; -use transmission_rpc::types::{TorrentAddArgs, TorrentAddedOrDuplicate}; +use transmission_rpc::types::{BasicAuth, Result, RpcResponse, TorrentAddArgs, TorrentAddedOrDuplicate}; use transmission_rpc::TransClient; #[tokio::main] @@ -13,12 +12,15 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } let add: TorrentAddArgs = TorrentAddArgs { - filename: Some("https://releases.ubuntu.com/20.04/ubuntu-20.04.2.0-desktop-amd64.iso.torrent".to_string()), + filename: Some( + "https://releases.ubuntu.com/20.04/ubuntu-20.04.2.0-desktop-amd64.iso.torrent" + .to_string(), + ), ..TorrentAddArgs::default() }; let res: RpcResponse = client.torrent_add(add).await?; diff --git a/examples/torrent-get.rs b/examples/torrent-get.rs index fb94d8c..28caec0 100644 --- a/examples/torrent-get.rs +++ b/examples/torrent-get.rs @@ -2,8 +2,9 @@ extern crate transmission_rpc; use dotenv::dotenv; use std::env; -use transmission_rpc::types::{BasicAuth, Result, RpcResponse}; -use transmission_rpc::types::{Id, Torrent, TorrentGetField, Torrents}; +use transmission_rpc::types::{ + BasicAuth, Id, Result, RpcResponse, Torrent, TorrentGetField, Torrents, +}; use transmission_rpc::TransClient; #[tokio::main] @@ -13,7 +14,7 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } @@ -27,15 +28,23 @@ async fn main() -> Result<()> { .collect(); println!("{:#?}", names); - let res1: RpcResponse> = client.torrent_get( + let res1: RpcResponse> = client + .torrent_get( Some(vec![TorrentGetField::Id, TorrentGetField::Name]), Some(vec![Id::Id(1), Id::Id(2), Id::Id(3)]), - ).await?; + ) + .await?; let first_three: Vec = res1 .arguments .torrents .iter() - .map(|it| {format!("{}. {}", &it.id.as_ref().unwrap(), &it.name.as_ref().unwrap())}) + .map(|it| { + format!( + "{}. {}", + &it.id.as_ref().unwrap(), + &it.name.as_ref().unwrap() + ) + }) .collect(); println!("{:#?}", first_three); @@ -46,13 +55,23 @@ async fn main() -> Result<()> { TorrentGetField::HashString, TorrentGetField::Name, ]), - Some(vec![Id::Hash(String::from("64b0d9a53ac9cd1002dad1e15522feddb00152fe",))]), - ).await?; + Some(vec![Id::Hash(String::from( + "64b0d9a53ac9cd1002dad1e15522feddb00152fe", + ))]), + ) + .await?; let info: Vec = res2 .arguments .torrents .iter() - .map(|it| {format!("{:5}. {:^45} {}", &it.id.as_ref().unwrap(), &it.hash_string.as_ref().unwrap(), &it.name.as_ref().unwrap())}) + .map(|it| { + format!( + "{:5}. {:^45} {}", + &it.id.as_ref().unwrap(), + &it.hash_string.as_ref().unwrap(), + &it.name.as_ref().unwrap() + ) + }) .collect(); println!("{:#?}", info); diff --git a/examples/torrent-remove.rs b/examples/torrent-remove.rs index 060c95c..0fed581 100644 --- a/examples/torrent-remove.rs +++ b/examples/torrent-remove.rs @@ -2,8 +2,7 @@ extern crate transmission_rpc; use dotenv::dotenv; use std::env; -use transmission_rpc::types::{BasicAuth, Result, RpcResponse}; -use transmission_rpc::types::{Id, Nothing}; +use transmission_rpc::types::{BasicAuth, Id, Nothing, Result, RpcResponse}; use transmission_rpc::TransClient; #[tokio::main] @@ -13,7 +12,7 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } diff --git a/examples/torrent-rename-path.rs b/examples/torrent-rename-path.rs index 59ee498..d639a43 100644 --- a/examples/torrent-rename-path.rs +++ b/examples/torrent-rename-path.rs @@ -1,19 +1,27 @@ extern crate transmission_rpc; -use std::env; use dotenv::dotenv; +use std::env; +use transmission_rpc::types::{BasicAuth, Id, Result, RpcResponse, TorrentRenamePath}; use transmission_rpc::TransClient; -use transmission_rpc::types::{Result, RpcResponse, BasicAuth}; -use transmission_rpc::types::{TorrentRenamePath, Id}; #[tokio::main] async fn main() -> Result<()> { dotenv().ok(); env_logger::init(); - let url= env::var("TURL")?; - let basic_auth = BasicAuth{user: env::var("TUSER")?, password: env::var("TPWD")?}; + let url = env::var("TURL")?; + let basic_auth = BasicAuth { + user: env::var("TUSER")?, + password: env::var("TPWD")?, + }; let mut client = TransClient::with_auth(&url, basic_auth); - let res: RpcResponse = client.torrent_rename_path(vec![Id::Id(1)], String::from("Folder/OldFile.jpg"), String::from("NewFile.jpg")).await?; + let res: RpcResponse = client + .torrent_rename_path( + vec![Id::Id(1)], + String::from("Folder/OldFile.jpg"), + String::from("NewFile.jpg"), + ) + .await?; println!("rename-path result: {:#?}", res); Ok(()) diff --git a/examples/torrent-set-location.rs b/examples/torrent-set-location.rs index 91f05b3..9a92720 100644 --- a/examples/torrent-set-location.rs +++ b/examples/torrent-set-location.rs @@ -2,8 +2,7 @@ extern crate transmission_rpc; use dotenv::dotenv; use std::env; -use transmission_rpc::types::{BasicAuth, Result, RpcResponse}; -use transmission_rpc::types::{Id, Nothing}; +use transmission_rpc::types::{BasicAuth, Id, Nothing, Result, RpcResponse}; use transmission_rpc::TransClient; #[tokio::main] @@ -13,15 +12,17 @@ async fn main() -> Result<()> { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } - let res: RpcResponse = client.torrent_set_location( + let res: RpcResponse = client + .torrent_set_location( vec![Id::Id(1)], String::from("/new/location"), Option::from(false), - ).await?; + ) + .await?; println!("Set-location result: {:?}", &res.is_ok()); Ok(()) diff --git a/src/lib.rs b/src/lib.rs index 784dbf5..aefa811 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,17 +9,11 @@ use serde::de::DeserializeOwned; pub mod types; -use types::BasicAuth; -use types::BlocklistUpdate; -use types::SessionGet; -use types::SessionStats; -use types::SessionClose; -use types::PortTest; -use types::FreeSpace; -use types::TorrentAction; -use types::{Id, Torrent, TorrentGetField, Torrents}; -use types::{Nothing, Result, RpcRequest, RpcResponse, RpcResponseArgument, TorrentRenamePath}; -use types::{TorrentAddArgs, TorrentAddedOrDuplicate}; +use types::{ + BasicAuth, BlocklistUpdate, FreeSpace, Id, Nothing, PortTest, Result, RpcRequest, RpcResponse, + RpcResponseArgument, SessionClose, SessionGet, SessionStats, Torrent, TorrentAction, + TorrentAddArgs, TorrentAddedOrDuplicate, TorrentGetField, TorrentRenamePath, Torrents, +}; const MAX_RETRIES: usize = 5; @@ -49,6 +43,7 @@ pub struct TransClient { impl TransClient { /// Returns HTTP(S) client with configured Basic Auth + #[must_use] pub fn with_auth(url: &str, basic_auth: BasicAuth) -> TransClient { TransClient { url: url.to_string(), @@ -59,6 +54,7 @@ impl TransClient { } /// Returns HTTP(S) client + #[must_use] pub fn new(url: &str) -> TransClient { TransClient { url: url.to_string(), @@ -71,11 +67,13 @@ impl TransClient { /// Prepares a request for provided server and auth fn rpc_request(&self) -> reqwest::RequestBuilder { if let Some(auth) = &self.auth { - self.client.post(&self.url) + self.client + .post(&self.url) .basic_auth(&auth.user, Some(&auth.password)) } else { self.client.post(&self.url) - }.header(CONTENT_TYPE, "application/json") + } + .header(CONTENT_TYPE, "application/json") } /// Performs a session get call @@ -482,13 +480,13 @@ impl TransClient { /// /// ``` /// extern crate transmission_rpc; - /// + /// /// use std::env; /// use dotenv::dotenv; /// use transmission_rpc::TransClient; /// use transmission_rpc::types::{Result, RpcResponse, BasicAuth}; /// use transmission_rpc::types::{TorrentRenamePath, Id}; - /// + /// /// #[tokio::main] /// async fn main() -> Result<()> { /// dotenv().ok(); @@ -498,7 +496,7 @@ impl TransClient { /// let mut client = TransClient::with_auth(&url, basic_auth); /// let res: RpcResponse = client.torrent_rename_path(vec![Id::Id(1)], String::from("Folder/OldFile.jpg"), String::from("NewFile.jpg")).await?; /// println!("rename-path result: {:#?}", res); - /// + /// /// Ok(()) /// } /// ``` @@ -547,10 +545,15 @@ impl TransClient { /// Ok(()) /// } /// ``` + /// + /// # Panics + /// Either metainfo or torrent filename must be set or this call will panic. + /// pub async fn torrent_add(&mut self, add: TorrentAddArgs) -> Result> { - if add.metainfo == None && add.filename == None { - panic!("Metainfo or Filename should be provided") - } + assert!( + !(add.metainfo == None && add.filename == None), + "Metainfo or Filename should be provided" + ); self.call(RpcRequest::torrent_add(add)).await } @@ -560,23 +563,21 @@ impl TransClient { /// /// Any IO Error or Deserialization error async fn call(&mut self, request: RpcRequest) -> Result> - where - RS: RpcResponseArgument + DeserializeOwned + std::fmt::Debug, + where + RS: RpcResponseArgument + DeserializeOwned + std::fmt::Debug, { let mut remaining_retries = MAX_RETRIES; loop { - if remaining_retries <= 0 { - return Err(From::from(TransError::MaxRetriesReached)); - } - remaining_retries -= 1; + remaining_retries = remaining_retries + .checked_sub(1) + .ok_or(TransError::MaxRetriesReached)?; info!("Loaded auth: {:?}", &self.auth); let rq = match &self.session_id { None => self.rpc_request(), - Some(id) => { - self.rpc_request().header("X-Transmission-Session-Id", id) - } - }.json(&request); + Some(id) => self.rpc_request().header("X-Transmission-Session-Id", id), + } + .json(&request); info!( "Request body: {:?}", @@ -586,23 +587,20 @@ impl TransClient { ); let rsp: reqwest::Response = rq.send().await?; - match rsp.status() { - StatusCode::CONFLICT => { - let session_id = rsp.headers() - .get("X-Transmission-Session-Id") - .ok_or(TransError::NoSessionIdReceived)? - .to_str()?; - self.session_id = Some(String::from(session_id)); + if matches!(rsp.status(), StatusCode::CONFLICT) { + let session_id = rsp + .headers() + .get("X-Transmission-Session-Id") + .ok_or(TransError::NoSessionIdReceived)? + .to_str()?; + self.session_id = Some(String::from(session_id)); - info!("Got new session_id: {}. Retrying request.", session_id); - continue; - } - _ => { - let rpc_response: RpcResponse = rsp.json().await?; - info!("Response body: {:#?}", rpc_response); + info!("Got new session_id: {}. Retrying request.", session_id); + } else { + let rpc_response: RpcResponse = rsp.json().await?; + info!("Response body: {:#?}", rpc_response); - return Ok(rpc_response) - } + return Ok(rpc_response); } } } @@ -633,7 +631,7 @@ mod tests { let url = env::var("TURL")?; let mut client; if let (Ok(user), Ok(password)) = (env::var("TUSER"), env::var("TPWD")) { - client = TransClient::with_auth(&url, BasicAuth {user, password}); + client = TransClient::with_auth(&url, BasicAuth { user, password }); } else { client = TransClient::new(&url); } diff --git a/src/types/mod.rs b/src/types/mod.rs index 5b26388..00ec0dd 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -9,24 +9,13 @@ pub struct BasicAuth { pub password: String, } -pub use self::request::ArgumentFields; -pub use self::request::Id; pub(crate) use self::request::RpcRequest; -pub use self::request::TorrentAction; -pub use self::request::TorrentAddArgs; -pub use self::request::TorrentGetField; -pub use self::request::TorrentRenamePathArgs; +pub use self::request::{ + ArgumentFields, Id, TorrentAction, TorrentAddArgs, TorrentGetField, TorrentRenamePathArgs, +}; -pub use self::response::Nothing; -pub use self::response::RpcResponse; pub(crate) use self::response::RpcResponseArgument; -pub use self::response::SessionGet; -pub use self::response::SessionStats; -pub use self::response::SessionClose; -pub use self::response::BlocklistUpdate; -pub use self::response::PortTest; -pub use self::response::FreeSpace; -pub use self::response::Torrent; -pub use self::response::TorrentAddedOrDuplicate; -pub use self::response::Torrents; -pub use self::response::TorrentRenamePath; +pub use self::response::{ + BlocklistUpdate, FreeSpace, Nothing, PortTest, RpcResponse, SessionClose, SessionGet, + SessionStats, Torrent, TorrentAddedOrDuplicate, TorrentRenamePath, Torrents, +}; diff --git a/src/types/request.rs b/src/types/request.rs index ae80645..f14b787 100644 --- a/src/types/request.rs +++ b/src/types/request.rs @@ -40,7 +40,7 @@ impl RpcRequest { pub fn free_space(path: String) -> RpcRequest { RpcRequest { method: String::from("free-space"), - arguments: Some(Args::FreeSpaceArgs(FreeSpaceArgs { path })), + arguments: Some(Args::FreeSpace(FreeSpaceArgs { path })), } } @@ -53,13 +53,13 @@ impl RpcRequest { pub fn torrent_get(fields: Option>, ids: Option>) -> RpcRequest { let string_fields = fields - .unwrap_or(TorrentGetField::all()) + .unwrap_or_else(TorrentGetField::all) .iter() - .map(|f| f.to_str()) + .map(TorrentGetField::to_str) .collect(); RpcRequest { method: String::from("torrent-get"), - arguments: Some(Args::TorrentGetArgs(TorrentGetArgs { + arguments: Some(Args::TorrentGet(TorrentGetArgs { fields: Some(string_fields), ids, })), @@ -69,7 +69,7 @@ impl RpcRequest { pub fn torrent_remove(ids: Vec, delete_local_data: bool) -> RpcRequest { RpcRequest { method: String::from("torrent-remove"), - arguments: Some(Args::TorrentRemoveArgs(TorrentRemoveArgs { + arguments: Some(Args::TorrentRemove(TorrentRemoveArgs { ids, delete_local_data, })), @@ -79,21 +79,25 @@ impl RpcRequest { pub fn torrent_add(add: TorrentAddArgs) -> RpcRequest { RpcRequest { method: String::from("torrent-add"), - arguments: Some(Args::TorrentAddArgs(add)), + arguments: Some(Args::TorrentAdd(add)), } } pub fn torrent_action(action: TorrentAction, ids: Vec) -> RpcRequest { RpcRequest { method: action.to_str(), - arguments: Some(Args::TorrentActionArgs(TorrentActionArgs { ids })), + arguments: Some(Args::TorrentAction(TorrentActionArgs { ids })), } } - pub fn torrent_set_location(ids: Vec, location: String, move_from: Option, ) -> RpcRequest { + pub fn torrent_set_location( + ids: Vec, + location: String, + move_from: Option, + ) -> RpcRequest { RpcRequest { method: String::from("torrent-set-location"), - arguments: Some(Args::TorrentSetLocationArgs(TorrentSetLocationArgs { + arguments: Some(Args::TorrentSetLocation(TorrentSetLocationArgs { ids, location, move_from, @@ -104,11 +108,11 @@ impl RpcRequest { pub fn torrent_rename_path(ids: Vec, path: String, name: String) -> RpcRequest { RpcRequest { method: String::from("torrent-rename-path"), - arguments: Some(Args::TorrentRenamePathArgs(TorrentRenamePathArgs { + arguments: Some(Args::TorrentRenamePath(TorrentRenamePathArgs { ids, path, - name - })) + name, + })), } } } @@ -118,13 +122,13 @@ impl ArgumentFields for TorrentGetField {} #[derive(Serialize, Debug, Clone)] #[serde(untagged)] pub enum Args { - FreeSpaceArgs(FreeSpaceArgs), - TorrentGetArgs(TorrentGetArgs), - TorrentActionArgs(TorrentActionArgs), - TorrentRemoveArgs(TorrentRemoveArgs), - TorrentAddArgs(TorrentAddArgs), - TorrentSetLocationArgs(TorrentSetLocationArgs), - TorrentRenamePathArgs(TorrentRenamePathArgs), + FreeSpace(FreeSpaceArgs), + TorrentGet(TorrentGetArgs), + TorrentAction(TorrentActionArgs), + TorrentRemove(TorrentRemoveArgs), + TorrentAdd(TorrentAddArgs), + TorrentSetLocation(TorrentSetLocationArgs), + TorrentRenamePath(TorrentRenamePathArgs), } #[derive(Serialize, Debug, Clone)] @@ -185,7 +189,7 @@ pub enum Id { Hash(String), } -#[derive(Serialize, Debug, Clone)] +#[derive(Serialize, Debug, Default, Clone)] pub struct TorrentAddArgs { #[serde(skip_serializing_if = "Option::is_none")] pub cookies: Option, @@ -224,26 +228,7 @@ pub struct TorrentAddArgs { pub priority_normal: Option>, } -impl Default for TorrentAddArgs { - fn default() -> Self { - TorrentAddArgs { - cookies: None, - download_dir: None, - filename: None, - metainfo: None, - paused: None, - peer_limit: None, - bandwidth_priority: None, - files_wanted: None, - files_unwanted: None, - priority_high: None, - priority_low: None, - priority_normal: None, - } - } -} - -#[derive(Clone, IntoEnumIterator)] +#[derive(Clone, Copy, IntoEnumIterator)] pub enum TorrentGetField { Id, Addeddate, @@ -278,16 +263,18 @@ pub enum TorrentGetField { Webseedssendingtous, Wanted, Priorities, - Filestats + Filestats, } impl TorrentGetField { + #[must_use] pub fn all() -> Vec { TorrentGetField::into_enum_iter().collect() } } impl TorrentGetField { + #[must_use] pub fn to_str(&self) -> String { match self { TorrentGetField::Id => "id", @@ -324,10 +311,12 @@ impl TorrentGetField { TorrentGetField::Wanted => "wanted", TorrentGetField::Priorities => "priorities", TorrentGetField::Filestats => "fileStats", - }.to_string() + } + .to_string() } } +#[derive(Clone, Copy, Debug)] pub enum TorrentAction { Start, Stop, @@ -337,6 +326,7 @@ pub enum TorrentAction { } impl TorrentAction { + #[must_use] pub fn to_str(&self) -> String { match self { TorrentAction::Start => "torrent-start", @@ -344,6 +334,7 @@ impl TorrentAction { TorrentAction::StartNow => "torrent-start-now", TorrentAction::Verify => "torrent-verify", TorrentAction::Reannounce => "torrent-reannounce", - }.to_string() + } + .to_string() } } diff --git a/src/types/response.rs b/src/types/response.rs index 41af839..bd7f1db 100644 --- a/src/types/response.rs +++ b/src/types/response.rs @@ -142,7 +142,7 @@ pub struct Stats { #[serde(rename = "secondsActive")] pub seconds_active: i64, #[serde(rename = "sessionCount")] - pub session_count: Option + pub session_count: Option, } #[derive(Deserialize, Debug)] @@ -187,10 +187,9 @@ pub enum TorrentAddedOrDuplicate { impl RpcResponseArgument for TorrentAddedOrDuplicate {} #[derive(Deserialize, Debug)] -pub struct TorrentRenamePath{ +pub struct TorrentRenamePath { pub path: Option, pub name: Option, pub id: Option, - } impl RpcResponseArgument for TorrentRenamePath {}