mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
implement set/get_ui_config() resurrection (#2672)
* Implement set/get_ui_config and use those methods if config string starts with 'ui.' * use ensure! macro
This commit is contained in:
@@ -359,6 +359,11 @@ char* dc_get_blobdir (const dc_context_t* context);
|
||||
* to not mess up with non-delivery-reports or read-receipts.
|
||||
* 0=no limit (default).
|
||||
* Changes affect future messages only.
|
||||
* - `ui.*` = All keys prefixed by `ui.` can be used by the user-interfaces for system-specific purposes.
|
||||
* The prefix should be followed by the system and maybe subsystem,
|
||||
* eg. `ui.desktop.foo`, `ui.desktop.linux.bar`, `ui.android.foo`, `ui.dc40.bar`, `ui.bot.simplebot.baz`.
|
||||
* These keys go to backups and allow easy per-account settings when using @ref dc_accounts_t,
|
||||
* however, are not handled by the core otherwise.
|
||||
*
|
||||
* If you want to retrieve a value, use dc_get_config().
|
||||
*
|
||||
|
||||
@@ -134,20 +134,30 @@ pub unsafe extern "C" fn dc_set_config(
|
||||
}
|
||||
let ctx = &*context;
|
||||
let key = to_string_lossy(key);
|
||||
match config::Config::from_str(&key) {
|
||||
Ok(key) => block_on(async move {
|
||||
let value = to_opt_string_lossy(value);
|
||||
ctx.set_config(key, value.as_deref())
|
||||
let value = to_opt_string_lossy(value);
|
||||
|
||||
block_on(async move {
|
||||
if key.starts_with("ui.") {
|
||||
ctx.set_ui_config(&key, value.as_deref())
|
||||
.await
|
||||
.with_context(|| format!("Can't set {} to {:?}", key, value))
|
||||
.log_err(ctx, "dc_set_config() failed")
|
||||
.is_ok() as libc::c_int
|
||||
}),
|
||||
Err(_) => {
|
||||
warn!(ctx, "dc_set_config(): invalid key");
|
||||
0
|
||||
} else {
|
||||
match config::Config::from_str(&key) {
|
||||
Ok(key) => ctx
|
||||
.set_config(key, value.as_deref())
|
||||
.await
|
||||
.with_context(|| format!("Can't set {} to {:?}", key, value))
|
||||
.log_err(ctx, "dc_set_config() failed")
|
||||
.is_ok() as libc::c_int,
|
||||
Err(_) => {
|
||||
warn!(ctx, "dc_set_config(): invalid key");
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -160,20 +170,33 @@ pub unsafe extern "C" fn dc_get_config(
|
||||
return "".strdup();
|
||||
}
|
||||
let ctx = &*context;
|
||||
match config::Config::from_str(&to_string_lossy(key)) {
|
||||
Ok(key) => block_on(async move {
|
||||
ctx.get_config(key)
|
||||
|
||||
let key = to_string_lossy(key);
|
||||
|
||||
block_on(async move {
|
||||
if key.starts_with("ui.") {
|
||||
ctx.get_ui_config(&key)
|
||||
.await
|
||||
.log_err(ctx, "Can't get config")
|
||||
.log_err(ctx, "Can't get ui-config")
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default()
|
||||
.strdup()
|
||||
}),
|
||||
Err(_) => {
|
||||
warn!(ctx, "dc_get_config(): invalid key");
|
||||
"".strdup()
|
||||
} else {
|
||||
match config::Config::from_str(&key) {
|
||||
Ok(key) => ctx
|
||||
.get_config(key)
|
||||
.await
|
||||
.log_err(ctx, "Can't get config")
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default()
|
||||
.strdup(),
|
||||
Err(_) => {
|
||||
warn!(ctx, "dc_get_config(): invalid key");
|
||||
"".strdup()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! # Key-value configuration management.
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{ensure, Result};
|
||||
use strum::{EnumProperty, IntoEnumIterator};
|
||||
use strum_macros::{AsRefStr, Display, EnumIter, EnumProperty, EnumString};
|
||||
|
||||
@@ -337,6 +337,21 @@ impl Context {
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sets an ui-specific key-value pair.
|
||||
/// Keys must be prefixed by `ui.`
|
||||
/// and should be followed by the name of the system and maybe subsystem,
|
||||
/// eg. `ui.desktop.linux.foo`, `ui.desktop.macos.bar`, `ui.ios.foobar`.
|
||||
pub async fn set_ui_config(&self, key: &str, value: Option<&str>) -> Result<()> {
|
||||
ensure!(key.starts_with("ui."), "set_ui_config(): prefix missing.");
|
||||
self.sql.set_raw_config(key, value).await
|
||||
}
|
||||
|
||||
/// Gets an ui-specific value set by set_ui_config().
|
||||
pub async fn get_ui_config(&self, key: &str) -> Result<Option<String>> {
|
||||
ensure!(key.starts_with("ui."), "get_ui_config(): prefix missing.");
|
||||
self.sql.get_raw_config(key).await
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all available configuration keys concated together.
|
||||
@@ -389,4 +404,25 @@ mod tests {
|
||||
let media_quality = constants::MediaQuality::from_i32(media_quality).unwrap_or_default();
|
||||
assert_eq!(media_quality, constants::MediaQuality::Worse);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_ui_config() -> Result<()> {
|
||||
let t = TestContext::new().await;
|
||||
|
||||
assert_eq!(t.get_ui_config("ui.desktop.linux.systray").await?, None);
|
||||
|
||||
t.set_ui_config("ui.android.screen_security", Some("safe"))
|
||||
.await?;
|
||||
assert_eq!(
|
||||
t.get_ui_config("ui.android.screen_security").await?,
|
||||
Some("safe".to_string())
|
||||
);
|
||||
|
||||
t.set_ui_config("ui.android.screen_security", None).await?;
|
||||
assert_eq!(t.get_ui_config("ui.android.screen_security").await?, None);
|
||||
|
||||
assert!(t.set_ui_config("configured", Some("bar")).await.is_err());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user