use serde::{Deserialize, Serialize};
use std::sync::Arc;
use crate::error::{Error, Result};
use crate::webcash::PublicWebcash;
use crate::server::{HealthResponse, ReplaceRequest, ReplaceResponse, TargetResponse, MiningReportRequest, MiningReportResponse};
#[derive(Debug, Clone)]
pub struct IOSServerConfig {
pub base_url: String,
pub timeout_seconds: u64,
pub tls_config: Option<IOSCustomTLS>,
}
impl Default for IOSServerConfig {
fn default() -> Self {
IOSServerConfig {
base_url: "https://webcash.org".to_string(),
timeout_seconds: 30,
tls_config: None,
}
}
}
#[derive(Debug, Clone)]
pub struct IOSCustomTLS {
pub certificate_data: Option<Vec<u8>>,
pub root_certificates: Vec<Vec<u8>>,
pub client_certificate: Option<Vec<u8>>,
pub client_key: Option<Vec<u8>>,
}
pub struct IOSServerClient {
config: IOSServerConfig,
_client: Arc<IOSHttpClient>,
}
struct IOSHttpClient {
}
impl IOSServerClient {
pub fn new() -> Result<Self> {
Self::with_config(IOSServerConfig::default())
}
pub fn with_config(config: IOSServerConfig) -> Result<Self> {
let client = Arc::new(IOSHttpClient::new(&config)?);
Ok(IOSServerClient {
config,
_client: client,
})
}
pub async fn health_check(&self, webcash: &[PublicWebcash]) -> Result<HealthResponse> {
let mut request_data = Vec::new();
for wc in webcash {
request_data.push(wc.to_string());
}
let url = format!("{}/api/v1/health_check", self.config.base_url);
self.perform_request("POST", &url, Some(&request_data)).await
}
pub async fn replace(&self, request: &ReplaceRequest) -> Result<ReplaceResponse> {
let url = format!("{}/api/v1/replace", self.config.base_url);
self.perform_request("POST", &url, Some(request)).await
}
pub async fn get_target(&self) -> Result<TargetResponse> {
let url = format!("{}/api/v1/target", self.config.base_url);
self.perform_request("GET", &url, None::<&()>).await
}
pub async fn submit_mining_report(&self, report: &MiningReportRequest) -> Result<MiningReportResponse> {
let url = format!("{}/api/v1/mining_report", self.config.base_url);
self.perform_request("POST", &url, Some(report)).await
}
async fn perform_request<T: Serialize, R: for<'de> Deserialize<'de>>(
&self,
method: &str,
url: &str,
body: Option<&T>,
) -> Result<R> {
Err(Error::Server("iOS networking implementation not yet complete".to_string()))
}
}
impl IOSHttpClient {
fn new(_config: &IOSServerConfig) -> Result<Self> {
Ok(IOSHttpClient {})
}
}
#[async_trait::async_trait]
impl crate::server::ServerClientTrait for IOSServerClient {
async fn health_check(&self, webcash: &[PublicWebcash]) -> Result<HealthResponse> {
self.health_check(webcash).await
}
async fn replace(&self, request: &ReplaceRequest) -> Result<ReplaceResponse> {
self.replace(request).await
}
async fn get_target(&self) -> Result<TargetResponse> {
self.get_target().await
}
async fn submit_mining_report(&self, report: &MiningReportRequest) -> Result<MiningReportResponse> {
self.submit_mining_report(report).await
}
}