From fc8ba9de909866175dd20bb0f8e8f1aee7990b3f Mon Sep 17 00:00:00 2001 From: Alekos Filini Date: Mon, 29 Aug 2022 11:42:29 +0200 Subject: [PATCH] Use idiomatic rust for the `raw_call` method --- src/api.rs | 6 +++++- src/client.rs | 14 ++++++++++++-- src/raw_client.rs | 38 ++++++++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/api.rs b/src/api.rs index 1781847..5ec7775 100644 --- a/src/api.rs +++ b/src/api.rs @@ -66,7 +66,11 @@ pub trait ElectrumApi { } /// Executes the requested API call returning the raw answer. - fn raw_call(&self, call: &Call) -> Result; + fn raw_call( + &self, + method_name: &str, + params: impl IntoIterator, + ) -> Result; /// Execute a queue of calls stored in a [`Batch`](../batch/struct.Batch.html) struct. Returns /// `Ok()` **only if** all of the calls are successful. The order of the JSON `Value`s returned diff --git a/src/client.rs b/src/client.rs index 5fda929..67cba8a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -168,8 +168,18 @@ impl Client { impl ElectrumApi for Client { #[inline] - fn raw_call(&self, call: &Call) -> Result { - impl_inner_call!(self, raw_call, call) + fn raw_call( + &self, + method_name: &str, + params: impl IntoIterator, + ) -> Result { + // We can't passthrough this method to the inner client because it would require the + // `params` argument to also be `Copy` (because it's used multiple times for multiple + // retries). To avoid adding this extra trait bound we instead re-direct this call to the internal + // `RawClient::internal_raw_call_with_vec` method. + + let vec = params.into_iter().collect::>(); + impl_inner_call!(self, internal_raw_call_with_vec, method_name, vec.clone()); } #[inline] diff --git a/src/raw_client.rs b/src/raw_client.rs index 93eeba9..350bd92 100644 --- a/src/raw_client.rs +++ b/src/raw_client.rs @@ -3,7 +3,6 @@ //! This module contains the definition of the raw client that wraps the transport method use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque}; -use std::convert::TryFrom; use std::io::{BufRead, BufReader, Read, Write}; use std::mem::drop; use std::net::{TcpStream, ToSocketAddrs}; @@ -348,6 +347,8 @@ impl RawClient { validate_domain: bool, tcp_stream: TcpStream, ) -> Result { + use std::convert::TryFrom; + let builder = ClientConfig::builder().with_safe_defaults(); let config = if validate_domain { @@ -658,6 +659,21 @@ impl RawClient { Ok(()) } + pub(crate) fn internal_raw_call_with_vec( + &self, + method_name: &str, + params: Vec, + ) -> Result { + let req = Request::new_id( + self.last_id.fetch_add(1, Ordering::SeqCst), + &method_name, + params, + ); + let result = self.call(req)?; + + Ok(result) + } + #[inline] #[cfg(feature = "debug-calls")] fn increment_calls(&self) { @@ -670,15 +686,12 @@ impl RawClient { } impl ElectrumApi for RawClient { - fn raw_call(&self, call: &Call) -> Result { - let req = Request::new_id( - self.last_id.fetch_add(1, Ordering::SeqCst), - &call.0, - call.1.to_vec(), - ); - let result = self.call(req)?; - - Ok(result) + fn raw_call( + &self, + method_name: &str, + params: impl IntoIterator, + ) -> Result { + self.internal_raw_call_with_vec(method_name, params.into_iter().collect()) } fn batch_call(&self, batch: &Batch) -> Result, Error> { @@ -1312,9 +1325,10 @@ mod test { ), Param::Bool(false), ]; - let call = ("blockchain.transaction.get".to_string(), params); - let resp = client.raw_call(&call).unwrap(); + let resp = client + .raw_call("blockchain.transaction.get", params) + .unwrap(); assert_eq!( resp,