use super::HttpEndpoint;
use crate::error::MechanicsError;
use boa_engine::{JsData, Trace};
use boa_gc::Finalize;
use serde::{Deserialize, Deserializer, Serialize};
use std::collections::HashMap;
#[derive(JsData, Trace, Finalize, Serialize, Clone, Debug)]
pub struct MechanicsConfig {
pub(crate) endpoints: HashMap<String, HttpEndpoint>,
}
impl MechanicsConfig {
pub fn new(endpoints: HashMap<String, HttpEndpoint>) -> Result<Self, MechanicsError> {
for (name, endpoint) in &endpoints {
endpoint.validate_config().map_err(|e| {
MechanicsError::runtime_pool(format!("invalid endpoint `{name}` config: {e}"))
})?;
}
Ok(Self { endpoints })
}
pub fn validate(&self) -> Result<(), MechanicsError> {
for (name, endpoint) in &self.endpoints {
endpoint.validate_config().map_err(|e| {
MechanicsError::runtime_pool(format!("invalid endpoint `{name}` config: {e}"))
})?;
}
Ok(())
}
pub fn with_endpoint<S: Into<String>>(
mut self,
name: S,
endpoint: HttpEndpoint,
) -> Result<Self, MechanicsError> {
let name = name.into();
endpoint.validate_config().map_err(|e| {
MechanicsError::runtime_pool(format!("invalid endpoint `{name}` config: {e}"))
})?;
self.endpoints.insert(name, endpoint);
Ok(self)
}
pub fn with_endpoint_overrides(
mut self,
overrides: HashMap<String, HttpEndpoint>,
) -> Result<Self, MechanicsError> {
for (name, endpoint) in overrides {
endpoint.validate_config().map_err(|e| {
MechanicsError::runtime_pool(format!("invalid endpoint `{name}` config: {e}"))
})?;
self.endpoints.insert(name, endpoint);
}
Ok(self)
}
pub fn without_endpoint(mut self, name: &str) -> Self {
self.endpoints.remove(name);
self
}
}
impl<'de> Deserialize<'de> for MechanicsConfig {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct RawMechanicsConfig {
endpoints: HashMap<String, HttpEndpoint>,
}
let raw = RawMechanicsConfig::deserialize(deserializer)?;
MechanicsConfig::new(raw.endpoints).map_err(serde::de::Error::custom)
}
}