use async_trait::async_trait;
use bytes::Bytes;
use std::{borrow::Borrow, fmt::Debug, net::SocketAddr, sync::Arc};
use futures_util::TryFutureExt;
use crate::api::adapter::{MockServerAdapter, ServerAdapterError};
use crate::{
api::adapter::ServerAdapterError::{MockNotFound, UpstreamError},
server::state::{HttpMockStateManager, StateManager},
};
use crate::common::data::{ActiveForwardingRule, ActiveMock, ActiveProxyRule, ActiveRecording};
use crate::common::data::{
ClosestMatch, ForwardingRuleConfig, MockDefinition, ProxyRuleConfig, RecordingRuleConfig,
RequestRequirements,
};
pub struct LocalMockServerAdapter {
pub addr: SocketAddr,
state: Arc<HttpMockStateManager>,
}
impl LocalMockServerAdapter {
pub fn new(addr: SocketAddr, local_state: Arc<HttpMockStateManager>) -> Self {
LocalMockServerAdapter {
addr,
state: local_state,
}
}
}
#[async_trait]
impl MockServerAdapter for LocalMockServerAdapter {
fn host(&self) -> String {
self.addr.ip().to_string()
}
fn port(&self) -> u16 {
self.addr.port()
}
fn address(&self) -> &SocketAddr {
&self.addr
}
async fn reset(&self) -> Result<(), ServerAdapterError> {
self.state.reset();
Ok(())
}
async fn create_mock(&self, mock: &MockDefinition) -> Result<ActiveMock, ServerAdapterError> {
let active_mock = self
.state
.add_mock(mock.clone(), false)
.map_err(|e| UpstreamError(e.to_string()))?;
Ok(active_mock)
}
async fn fetch_mock(&self, mock_id: usize) -> Result<ActiveMock, ServerAdapterError> {
let mock = self
.state
.read_mock(mock_id)
.map_err(|e| UpstreamError(e.to_string()))?
.ok_or_else(|| MockNotFound(mock_id))?;
Ok(mock)
}
async fn delete_mock(&self, mock_id: usize) -> Result<(), ServerAdapterError> {
self.state
.delete_mock(mock_id)
.map_err(|e| UpstreamError(format!("Cannot delete mock: {:?}", e)))?;
Ok(())
}
async fn verify(
&self,
mock_rr: &RequestRequirements,
) -> Result<Option<ClosestMatch>, ServerAdapterError> {
let closest_match = self
.state
.verify(mock_rr)
.map_err(|e| UpstreamError(format!("Cannot delete mock: {:?}", e)))?;
Ok(closest_match)
}
async fn create_forwarding_rule(
&self,
config: ForwardingRuleConfig,
) -> Result<ActiveForwardingRule, ServerAdapterError> {
Ok(self.state.create_forwarding_rule(config))
}
async fn delete_forwarding_rule(&self, id: usize) -> Result<(), ServerAdapterError> {
self.state.delete_forwarding_rule(id);
Ok(())
}
async fn create_proxy_rule(
&self,
config: ProxyRuleConfig,
) -> Result<ActiveProxyRule, ServerAdapterError> {
Ok(self.state.create_proxy_rule(config))
}
async fn delete_proxy_rule(&self, id: usize) -> Result<(), ServerAdapterError> {
self.state.delete_proxy_rule(id);
Ok(())
}
async fn create_recording(
&self,
config: RecordingRuleConfig,
) -> Result<ActiveRecording, ServerAdapterError> {
Ok(self.state.create_recording(config))
}
async fn delete_recording(&self, id: usize) -> Result<(), ServerAdapterError> {
self.state.delete_recording(id);
Ok(())
}
#[cfg(feature = "record")]
async fn export_recording(&self, id: usize) -> Result<Option<Bytes>, ServerAdapterError> {
Ok(self
.state
.export_recording(id)
.map_err(|err| UpstreamError(err.to_string()))?)
}
#[cfg(feature = "record")]
async fn create_mocks_from_recording<'a>(
&self,
recording_file_content: &'a str,
) -> Result<Vec<usize>, ServerAdapterError> {
Ok(self
.state
.load_mocks_from_recording(recording_file_content)
.map_err(|err| UpstreamError(err.to_string()))?)
}
}