Skip to content

Commit 3d0f52c

Browse files
committed
feat: allow references to ElectrumApi impls to also impl it
1 parent 83747b1 commit 3d0f52c

File tree

1 file changed

+371
-0
lines changed

1 file changed

+371
-0
lines changed

src/api.rs

Lines changed: 371 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,174 @@
22
33
use std::borrow::Borrow;
44
use std::convert::TryInto;
5+
use std::ops::Deref;
56

67
use bitcoin::consensus::encode::{deserialize, serialize};
78
use bitcoin::{block, Script, Transaction, Txid};
89

910
use crate::batch::Batch;
1011
use crate::types::*;
1112

13+
impl<E: Deref> ElectrumApi for E
14+
where
15+
E::Target: ElectrumApi,
16+
{
17+
fn raw_call(
18+
&self,
19+
method_name: &str,
20+
params: impl IntoIterator<Item = Param>,
21+
) -> Result<serde_json::Value, Error> {
22+
(**self).raw_call(method_name, params)
23+
}
24+
25+
fn batch_call(&self, batch: &Batch) -> Result<Vec<serde_json::Value>, Error> {
26+
(**self).batch_call(batch)
27+
}
28+
29+
fn block_headers_subscribe_raw(&self) -> Result<RawHeaderNotification, Error> {
30+
(**self).block_headers_subscribe_raw()
31+
}
32+
33+
fn block_headers_pop_raw(&self) -> Result<Option<RawHeaderNotification>, Error> {
34+
(**self).block_headers_pop_raw()
35+
}
36+
37+
fn block_header_raw(&self, height: usize) -> Result<Vec<u8>, Error> {
38+
(**self).block_header_raw(height)
39+
}
40+
41+
fn block_headers(&self, start_height: usize, count: usize) -> Result<GetHeadersRes, Error> {
42+
(**self).block_headers(start_height, count)
43+
}
44+
45+
fn estimate_fee(&self, number: usize) -> Result<f64, Error> {
46+
(**self).estimate_fee(number)
47+
}
48+
49+
fn relay_fee(&self) -> Result<f64, Error> {
50+
(**self).relay_fee()
51+
}
52+
53+
fn script_subscribe(&self, script: &Script) -> Result<Option<ScriptStatus>, Error> {
54+
(**self).script_subscribe(script)
55+
}
56+
57+
fn batch_script_subscribe<'s, I>(&self, scripts: I) -> Result<Vec<Option<ScriptStatus>>, Error>
58+
where
59+
I: IntoIterator + Clone,
60+
I::Item: Borrow<&'s Script>,
61+
{
62+
(**self).batch_script_subscribe(scripts)
63+
}
64+
65+
fn script_unsubscribe(&self, script: &Script) -> Result<bool, Error> {
66+
(**self).script_unsubscribe(script)
67+
}
68+
69+
fn script_pop(&self, script: &Script) -> Result<Option<ScriptStatus>, Error> {
70+
(**self).script_pop(script)
71+
}
72+
73+
fn script_get_balance(&self, script: &Script) -> Result<GetBalanceRes, Error> {
74+
(**self).script_get_balance(script)
75+
}
76+
77+
fn batch_script_get_balance<'s, I>(&self, scripts: I) -> Result<Vec<GetBalanceRes>, Error>
78+
where
79+
I: IntoIterator + Clone,
80+
I::Item: Borrow<&'s Script>,
81+
{
82+
(**self).batch_script_get_balance(scripts)
83+
}
84+
85+
fn script_get_history(&self, script: &Script) -> Result<Vec<GetHistoryRes>, Error> {
86+
(**self).script_get_history(script)
87+
}
88+
89+
fn batch_script_get_history<'s, I>(&self, scripts: I) -> Result<Vec<Vec<GetHistoryRes>>, Error>
90+
where
91+
I: IntoIterator + Clone,
92+
I::Item: Borrow<&'s Script>,
93+
{
94+
(**self).batch_script_get_history(scripts)
95+
}
96+
97+
fn script_list_unspent(&self, script: &Script) -> Result<Vec<ListUnspentRes>, Error> {
98+
(**self).script_list_unspent(script)
99+
}
100+
101+
fn batch_script_list_unspent<'s, I>(
102+
&self,
103+
scripts: I,
104+
) -> Result<Vec<Vec<ListUnspentRes>>, Error>
105+
where
106+
I: IntoIterator + Clone,
107+
I::Item: Borrow<&'s Script>,
108+
{
109+
(**self).batch_script_list_unspent(scripts)
110+
}
111+
112+
fn transaction_get_raw(&self, txid: &Txid) -> Result<Vec<u8>, Error> {
113+
(**self).transaction_get_raw(txid)
114+
}
115+
116+
fn batch_transaction_get_raw<'t, I>(&self, txids: I) -> Result<Vec<Vec<u8>>, Error>
117+
where
118+
I: IntoIterator + Clone,
119+
I::Item: Borrow<&'t Txid>,
120+
{
121+
(**self).batch_transaction_get_raw(txids)
122+
}
123+
124+
fn batch_block_header_raw<I>(&self, heights: I) -> Result<Vec<Vec<u8>>, Error>
125+
where
126+
I: IntoIterator + Clone,
127+
I::Item: Borrow<u32>,
128+
{
129+
(**self).batch_block_header_raw(heights)
130+
}
131+
132+
fn batch_estimate_fee<I>(&self, numbers: I) -> Result<Vec<f64>, Error>
133+
where
134+
I: IntoIterator + Clone,
135+
I::Item: Borrow<usize>,
136+
{
137+
(**self).batch_estimate_fee(numbers)
138+
}
139+
140+
fn transaction_broadcast_raw(&self, raw_tx: &[u8]) -> Result<Txid, Error> {
141+
(**self).transaction_broadcast_raw(raw_tx)
142+
}
143+
144+
fn transaction_get_merkle(&self, txid: &Txid, height: usize) -> Result<GetMerkleRes, Error> {
145+
(**self).transaction_get_merkle(txid, height)
146+
}
147+
148+
fn txid_from_pos(&self, height: usize, tx_pos: usize) -> Result<Txid, Error> {
149+
(**self).txid_from_pos(height, tx_pos)
150+
}
151+
152+
fn txid_from_pos_with_merkle(
153+
&self,
154+
height: usize,
155+
tx_pos: usize,
156+
) -> Result<TxidFromPosRes, Error> {
157+
(**self).txid_from_pos_with_merkle(height, tx_pos)
158+
}
159+
160+
fn server_features(&self) -> Result<ServerFeaturesRes, Error> {
161+
(**self).server_features()
162+
}
163+
164+
fn ping(&self) -> Result<(), Error> {
165+
(**self).ping()
166+
}
167+
168+
fn calls_made(&self) -> Result<usize, Error> {
169+
(**self).calls_made()
170+
}
171+
}
172+
12173
/// API calls exposed by an Electrum client
13174
pub trait ElectrumApi {
14175
/// Gets the block header for height `height`.
@@ -222,3 +383,213 @@ pub trait ElectrumApi {
222383
/// Returns the number of network calls made since the creation of the client.
223384
fn calls_made(&self) -> Result<usize, Error>;
224385
}
386+
387+
#[cfg(test)]
388+
mod test {
389+
use std::{borrow::Cow, sync::Arc};
390+
391+
use super::ElectrumApi;
392+
393+
#[derive(Debug, Clone)]
394+
struct FakeApi;
395+
396+
impl ElectrumApi for FakeApi {
397+
fn raw_call(
398+
&self,
399+
_: &str,
400+
_: impl IntoIterator<Item = super::Param>,
401+
) -> Result<serde_json::Value, super::Error> {
402+
unreachable!()
403+
}
404+
405+
fn batch_call(&self, _: &crate::Batch) -> Result<Vec<serde_json::Value>, super::Error> {
406+
unreachable!()
407+
}
408+
409+
fn block_headers_subscribe_raw(
410+
&self,
411+
) -> Result<super::RawHeaderNotification, super::Error> {
412+
unreachable!()
413+
}
414+
415+
fn block_headers_pop_raw(
416+
&self,
417+
) -> Result<Option<super::RawHeaderNotification>, super::Error> {
418+
unreachable!()
419+
}
420+
421+
fn block_header_raw(&self, _: usize) -> Result<Vec<u8>, super::Error> {
422+
unreachable!()
423+
}
424+
425+
fn block_headers(&self, _: usize, _: usize) -> Result<super::GetHeadersRes, super::Error> {
426+
unreachable!()
427+
}
428+
429+
fn estimate_fee(&self, _: usize) -> Result<f64, super::Error> {
430+
unreachable!()
431+
}
432+
433+
fn relay_fee(&self) -> Result<f64, super::Error> {
434+
unreachable!()
435+
}
436+
437+
fn script_subscribe(
438+
&self,
439+
_: &bitcoin::Script,
440+
) -> Result<Option<super::ScriptStatus>, super::Error> {
441+
unreachable!()
442+
}
443+
444+
fn batch_script_subscribe<'s, I>(
445+
&self,
446+
_: I,
447+
) -> Result<Vec<Option<super::ScriptStatus>>, super::Error>
448+
where
449+
I: IntoIterator + Clone,
450+
I::Item: std::borrow::Borrow<&'s bitcoin::Script>,
451+
{
452+
unreachable!()
453+
}
454+
455+
fn script_unsubscribe(&self, _: &bitcoin::Script) -> Result<bool, super::Error> {
456+
unreachable!()
457+
}
458+
459+
fn script_pop(
460+
&self,
461+
_: &bitcoin::Script,
462+
) -> Result<Option<super::ScriptStatus>, super::Error> {
463+
unreachable!()
464+
}
465+
466+
fn script_get_balance(
467+
&self,
468+
_: &bitcoin::Script,
469+
) -> Result<super::GetBalanceRes, super::Error> {
470+
unreachable!()
471+
}
472+
473+
fn batch_script_get_balance<'s, I>(
474+
&self,
475+
_: I,
476+
) -> Result<Vec<super::GetBalanceRes>, super::Error>
477+
where
478+
I: IntoIterator + Clone,
479+
I::Item: std::borrow::Borrow<&'s bitcoin::Script>,
480+
{
481+
unreachable!()
482+
}
483+
484+
fn script_get_history(
485+
&self,
486+
_: &bitcoin::Script,
487+
) -> Result<Vec<super::GetHistoryRes>, super::Error> {
488+
unreachable!()
489+
}
490+
491+
fn batch_script_get_history<'s, I>(
492+
&self,
493+
_: I,
494+
) -> Result<Vec<Vec<super::GetHistoryRes>>, super::Error>
495+
where
496+
I: IntoIterator + Clone,
497+
I::Item: std::borrow::Borrow<&'s bitcoin::Script>,
498+
{
499+
unreachable!()
500+
}
501+
502+
fn script_list_unspent(
503+
&self,
504+
_: &bitcoin::Script,
505+
) -> Result<Vec<super::ListUnspentRes>, super::Error> {
506+
unreachable!()
507+
}
508+
509+
fn batch_script_list_unspent<'s, I>(
510+
&self,
511+
_: I,
512+
) -> Result<Vec<Vec<super::ListUnspentRes>>, super::Error>
513+
where
514+
I: IntoIterator + Clone,
515+
I::Item: std::borrow::Borrow<&'s bitcoin::Script>,
516+
{
517+
unreachable!()
518+
}
519+
520+
fn transaction_get_raw(&self, _: &bitcoin::Txid) -> Result<Vec<u8>, super::Error> {
521+
unreachable!()
522+
}
523+
524+
fn batch_transaction_get_raw<'t, I>(&self, _: I) -> Result<Vec<Vec<u8>>, super::Error>
525+
where
526+
I: IntoIterator + Clone,
527+
I::Item: std::borrow::Borrow<&'t bitcoin::Txid>,
528+
{
529+
unreachable!()
530+
}
531+
532+
fn batch_block_header_raw<I>(&self, _: I) -> Result<Vec<Vec<u8>>, super::Error>
533+
where
534+
I: IntoIterator + Clone,
535+
I::Item: std::borrow::Borrow<u32>,
536+
{
537+
unreachable!()
538+
}
539+
540+
fn batch_estimate_fee<I>(&self, _: I) -> Result<Vec<f64>, super::Error>
541+
where
542+
I: IntoIterator + Clone,
543+
I::Item: std::borrow::Borrow<usize>,
544+
{
545+
unreachable!()
546+
}
547+
548+
fn transaction_broadcast_raw(&self, _: &[u8]) -> Result<bitcoin::Txid, super::Error> {
549+
unreachable!()
550+
}
551+
552+
fn transaction_get_merkle(
553+
&self,
554+
_: &bitcoin::Txid,
555+
_: usize,
556+
) -> Result<super::GetMerkleRes, super::Error> {
557+
unreachable!()
558+
}
559+
560+
fn txid_from_pos(&self, _: usize, _: usize) -> Result<bitcoin::Txid, super::Error> {
561+
unreachable!()
562+
}
563+
564+
fn txid_from_pos_with_merkle(
565+
&self,
566+
_: usize,
567+
_: usize,
568+
) -> Result<super::TxidFromPosRes, super::Error> {
569+
unreachable!()
570+
}
571+
572+
fn server_features(&self) -> Result<super::ServerFeaturesRes, super::Error> {
573+
unreachable!()
574+
}
575+
576+
fn ping(&self) -> Result<(), super::Error> {
577+
unreachable!()
578+
}
579+
580+
fn calls_made(&self) -> Result<usize, super::Error> {
581+
unreachable!()
582+
}
583+
}
584+
585+
fn is_impl<A: ElectrumApi>() {}
586+
587+
#[test]
588+
fn deref() {
589+
is_impl::<FakeApi>();
590+
is_impl::<&FakeApi>();
591+
is_impl::<Arc<FakeApi>>();
592+
is_impl::<Box<FakeApi>>();
593+
is_impl::<Cow<FakeApi>>();
594+
}
595+
}

0 commit comments

Comments
 (0)