use super::errors::GCMockingError;
use super::gateway_instance_ctx::{
GCGatewayMockInstanceCtx, GetEthernetInterfaceIntercept, GetLastDatapointValueIntercept, GetSerialInterfaceIntercept, LogIntercept,
PublishDatapointValueIntercept,
};
use super::gateway_mock::GCGatewayMock;
use crate::{GCDatapoint, GCPluginInstance};
use serde::Deserialize;
use serde_json::Value;
#[derive(Deserialize)]
struct DatapointName {
name: String,
}
#[derive(Deserialize)]
struct PluginConfigWithDatapoints {
#[serde(default)]
datapoint_publications: Vec<DatapointName>,
#[serde(default)]
datapoint_subscriptions: Vec<DatapointName>,
plugin_specific_config: Value,
}
pub struct GCGatewayMockBuilder {
pub(super) own_datapoints: Vec<GCDatapoint>,
pub(super) subscribed_datapoints: Vec<GCDatapoint>,
pub(super) core_ctx: Box<GCGatewayMockInstanceCtx>,
pub(super) config: Box<Value>,
pub(super) log_level: gc_abi::GCLogLevel,
}
impl Default for GCGatewayMockBuilder {
fn default() -> Self {
Self::new()
}
}
impl GCGatewayMockBuilder {
pub fn new() -> Self {
Self {
own_datapoints: Vec::new(),
subscribed_datapoints: Vec::new(),
core_ctx: GCGatewayMockInstanceCtx::new(),
config: Box::new(serde_json::Value::Null),
log_level: gc_abi::GCLogLevel::DEBUG,
}
}
pub fn add_own_datapoint(&mut self, datapoint: GCDatapoint) -> &mut Self {
self.own_datapoints.push(datapoint);
self
}
pub fn add_subscribed_datapoint(&mut self, datapoint: GCDatapoint) -> &mut Self {
self.subscribed_datapoints.push(datapoint);
self
}
pub fn set_log_level(&mut self, level: gc_abi::GCLogLevel) -> &mut Self {
self.log_level = level;
self
}
pub fn set_config(&mut self, config: String) -> Result<&mut Self, GCMockingError> {
*self.config = serde_json::from_str(&config)?;
Ok(self)
}
pub fn set_config_with_datapoints(&mut self, config: String) -> Result<&mut Self, GCMockingError> {
let config: PluginConfigWithDatapoints = serde_json::from_str(&config)?;
let mut last_id = self
.own_datapoints
.iter()
.chain(self.subscribed_datapoints.iter())
.map(|dp| dp.get_id())
.max()
.unwrap_or(0)
+ 1;
for dp in config.datapoint_publications {
self.add_own_datapoint(GCDatapoint::new(last_id, &dp.name, "", ""));
last_id += 1;
}
for dp in config.datapoint_subscriptions {
self.add_subscribed_datapoint(GCDatapoint::new(last_id, &dp.name, "", ""));
last_id += 1;
}
*self.config = config.plugin_specific_config;
Ok(self)
}
pub fn set_publish_datapoint_value_callback(&mut self, callback: Box<PublishDatapointValueIntercept>) -> &mut Self {
self.core_ctx.publish_datapoint_callback = callback;
self
}
pub fn set_log_callback(&mut self, callback: Box<LogIntercept>) -> &mut Self {
self.core_ctx.log_callback = callback;
self
}
pub fn set_get_last_datapoint_value_callback(&mut self, callback: Box<GetLastDatapointValueIntercept>) -> &mut Self {
self.core_ctx.get_last_datapoint_callback = callback;
self
}
pub fn set_get_ethernet_interface_callback(&mut self, callback: Box<GetEthernetInterfaceIntercept>) -> &mut Self {
self.core_ctx.get_ethernet_interface_callback = callback;
self
}
pub fn set_get_serial_interface_callback(&mut self, callback: Box<GetSerialInterfaceIntercept>) -> &mut Self {
self.core_ctx.get_serial_interface_callback = callback;
self
}
pub fn start<'a, T: GCPluginInstance<'a>>(self) -> Result<GCGatewayMock<'a, T>, GCMockingError> {
let mut mock = GCGatewayMock::new(self)?;
mock.start()?;
Ok(mock)
}
pub fn start_from<'a, T, F>(self, f: F) -> Result<GCGatewayMock<'a, T>, GCMockingError>
where
T: GCPluginInstance<'a>,
F: FnOnce(&'a crate::GCPluginInterface) -> Box<T> + 'a,
{
let mut mock = GCGatewayMock::new(self)?;
mock.start_from(f)?;
Ok(mock)
}
pub fn build<'a, T: GCPluginInstance<'a>>(self) -> Result<GCGatewayMock<'a, T>, GCMockingError> {
GCGatewayMock::new(self)
}
}