use crate::error::ApplyError;
use crate::view::{EditValue, NodeId};
use super::super::Workspace;
use super::super::id_index::NodeAddress;
use super::payload::{value_as_bool, value_as_integer, value_as_string, value_as_string_list};
impl Workspace {
pub(super) fn cmd_update_root_setting(
&mut self,
key: crate::view::RootSettingKey,
value: EditValue,
) -> Result<Vec<NodeId>, ApplyError> {
use crate::view::RootSettingKey::*;
match key {
ListenerIpAddress => {
let s = value_as_string(&value)?;
let listener = self.config.listener.get_or_insert_with(Default::default);
listener.ip_address = s;
}
ListenerPort => {
let n = value_as_integer(&value)?;
if !(0..=u16::MAX as i64).contains(&n) {
return Err(ApplyError::InvalidPayload {
reason: format!("port {} not in 0..=65535", n),
});
}
let listener = self.config.listener.get_or_insert_with(Default::default);
listener.port = n as u16;
}
ServiceFallbackRespondDir => {
let s = value_as_string(&value)?;
self.config.service.fallback_respond_dir = s;
}
ServiceStrategy => {
let s = value_as_string(&value)?;
use apimock_routing::Strategy;
let strategy = match s.as_str() {
"first_match" => Strategy::FirstMatch,
"uniform_random" => Strategy::UniformRandom { seed: None },
"weighted_random" => Strategy::WeightedRandom { seed: None },
"priority" => Strategy::Priority {
tiebreaker: apimock_routing::strategy::PriorityTiebreaker::FirstMatch,
},
"round_robin" => Strategy::RoundRobin,
other => {
return Err(ApplyError::InvalidPayload {
reason: format!("unknown strategy: `{}`", other),
});
}
};
self.config.service.strategy = Some(strategy);
}
TlsEnabled => {
let enabled = value_as_bool(&value)?;
if !enabled {
if let Some(listener) = self.config.listener.as_mut() {
listener.tls = None;
}
}
}
TlsCertFile => {
let s = value_as_string(&value)?;
let listener = self.config.listener.get_or_insert_with(Default::default);
let tls = listener.tls.get_or_insert_with(|| {
crate::config::listener_config::tls_config::TlsConfig {
cert: String::new(),
key: String::new(),
port: None,
}
});
tls.cert = s;
}
TlsKeyFile => {
let s = value_as_string(&value)?;
let listener = self.config.listener.get_or_insert_with(Default::default);
let tls = listener.tls.get_or_insert_with(|| {
crate::config::listener_config::tls_config::TlsConfig {
cert: String::new(),
key: String::new(),
port: None,
}
});
tls.key = s;
}
LogLevel => {
let s = value_as_string(&value)?;
let valid_levels = ["trace", "debug", "info", "warn", "error"];
if !valid_levels.contains(&s.as_str()) {
return Err(ApplyError::InvalidPayload {
reason: format!(
"invalid log level `{}` — valid: trace, debug, info, warn, error",
s
),
});
}
let _ = s; }
LogFile => {
let s = value_as_string(&value)?;
let _ = s; }
LogFormat => {
let s = value_as_string(&value)?;
let valid_formats = ["text", "json"];
if !valid_formats.contains(&s.as_str()) {
return Err(ApplyError::InvalidPayload {
reason: format!("invalid log format `{}` — valid: text, json", s),
});
}
let _ = s; }
FileTreeShowHidden => {
let b = value_as_bool(&value)?;
self.config
.file_tree_view
.get_or_insert_with(Default::default)
.show_hidden = b;
}
FileTreeBuiltinExcludes => {
let b = value_as_bool(&value)?;
self.config
.file_tree_view
.get_or_insert_with(Default::default)
.builtin_excludes = b;
}
FileTreeExtraExcludes => {
let list = value_as_string_list(&value)?;
self.config
.file_tree_view
.get_or_insert_with(Default::default)
.extra_excludes = list;
}
FileTreeInclude => {
let list = value_as_string_list(&value)?;
self.config
.file_tree_view
.get_or_insert_with(Default::default)
.include = list;
}
FileTreeRespectGitignore => {
let b = value_as_bool(&value)?;
self.config
.file_tree_view
.get_or_insert_with(Default::default)
.respect_gitignore = b;
}
TraceCaptureBody => {
log::info!("trace.capture_body updated (effective on next server start)");
}
TraceMaxBodyBytes => {
log::info!("trace.max_body_bytes updated (effective on next server start)");
}
}
let id = self
.ids
.id_for(NodeAddress::Root)
.expect("root id seeded at load");
Ok(vec![id])
}
}