use std::collections::HashMap;
use std::convert::{TryFrom, TryInto};
use std::net::ToSocketAddrs;
use tapyrus::{hashes::Hash, BlockHash};
use electrum_client::client::{
Client as RClient, ElectrumPlaintextStream, ElectrumProxyStream, ElectrumSslStream,
};
pub use electrum_client::types::ServerFeaturesRes;
pub use electrum_client::Error as ElectrumError;
use crate::electrum::ServerFeatures;
use crate::errors::{Error, ResultExt};
pub enum Client {
Tcp(RClient<ElectrumPlaintextStream>),
Ssl(RClient<ElectrumSslStream>),
ProxyTcp(RClient<ElectrumProxyStream>),
}
impl Client {
pub fn new<A: ToSocketAddrs>(socket_addr: A) -> Result<Self, ElectrumError> {
Ok(Client::Tcp(RClient::new(socket_addr)?))
}
pub fn new_ssl(domain_addr: (&str, u16)) -> Result<Self, ElectrumError> {
Ok(Client::Ssl(RClient::new_ssl(domain_addr, false)?))
}
pub fn new_proxy<A: ToSocketAddrs>(
target_addr: (&str, u16),
proxy_addr: A,
) -> Result<Self, ElectrumError> {
Ok(Client::ProxyTcp(RClient::new_proxy(
target_addr,
proxy_addr,
)?))
}
pub fn server_features(&mut self) -> Result<ServerFeatures, Error> {
match self {
Client::Tcp(c) => c.server_features(),
Client::Ssl(c) => c.server_features(),
Client::ProxyTcp(c) => c.server_features(),
}?
.try_into()
}
pub fn server_add_peer(&mut self, features: &ServerFeatures) -> Result<bool, ElectrumError> {
match self {
Client::Tcp(c) => c.server_add_peer(features),
Client::Ssl(c) => c.server_add_peer(features),
Client::ProxyTcp(c) => c.server_add_peer(features),
}
}
}
impl TryFrom<ServerFeaturesRes> for ServerFeatures {
type Error = Error;
fn try_from(mut features: ServerFeaturesRes) -> Result<Self, Self::Error> {
Ok(ServerFeatures {
hosts: HashMap::new(),
server_version: features.server_version,
protocol_min: features
.protocol_min
.parse()
.chain_err(|| "invalid protocol_min")?,
protocol_max: features
.protocol_max
.parse()
.chain_err(|| "invalid protocol_max")?,
pruning: features.pruning.map(|pruning| pruning as usize),
hash_function: features
.hash_function
.chain_err(|| "missing hash_function")?,
})
}
}