use alloc::string::String;
use crate::config_storage::{ConfigApi, ConfigChangedSet, ConfigLoadStore, ConfigStorage};
use embassy_sync::blocking_mutex::raw::RawMutex;
use embassy_sync::mutex::Mutex;
use serde::Deserialize;
#[derive(Deserialize)]
pub struct ConfigQuery {
pub set: Option<String>,
}
pub enum ConfigGroupResult {
Json(String),
Err(u16, String),
}
pub async fn handle_config_group<R, C, S, F>(
config: &Mutex<R, C>,
io: &Mutex<R, S>,
group: &str,
query: ConfigQuery,
buf: &mut [u8],
on_updated: Option<F>,
) -> ConfigGroupResult
where
R: RawMutex,
C: ConfigApi + ConfigLoadStore,
S: ConfigStorage,
F: Fn(C::ChangedSet),
{
let mut notify_changed = None;
if let Some(ref set_json) = query.set {
let mut config_guard = config.lock().await;
let changed = match config_guard.set_group_json(group, set_json) {
Ok(c) => c,
Err(e) => {
error!(
"handle_config_group: set_group_json failed for group {}: {}",
group,
crate::fmt::DisplayFmt(&e)
);
return ConfigGroupResult::Err(400, alloc::format!("{}", e));
}
};
if !changed.is_empty() {
let mut io_guard = io.lock().await;
if let Err(e) = config_guard.store_to(&mut *io_guard).await {
error!(
"handle_config_group: store_to failed for group {}: {}",
group,
crate::fmt::DisplayFmt(&e)
);
return ConfigGroupResult::Err(500, alloc::format!("{}", e));
}
notify_changed = Some(changed);
}
}
if let (Some(changed), Some(ref f)) = (notify_changed, on_updated) {
debug!("handle_config_group: calling on_updated");
f(changed);
debug!("handle_config_group: on_updated returned");
}
let config_guard = config.lock().await;
match config_guard.get_group_json(group, buf) {
Ok(len) => {
let json_str = String::from(core::str::from_utf8(&buf[..len]).unwrap_or(""));
ConfigGroupResult::Json(json_str)
}
Err(e) => ConfigGroupResult::Err(400, alloc::format!("{}", e)),
}
}