mirror of
https://github.com/chatmail/core.git
synced 2026-05-03 21:36:29 +03:00
Start implementing Ui config on top of the Config enum
This commit is contained in:
@@ -151,13 +151,7 @@ pub unsafe extern "C" fn dc_set_config(
|
|||||||
let context = &*context;
|
let context = &*context;
|
||||||
let key = dc_tools::as_str(key);
|
let key = dc_tools::as_str(key);
|
||||||
let value = as_opt_str(value);
|
let value = as_opt_str(value);
|
||||||
if key.starts_with(".ui") {
|
context.set_config_from_str(key, value).is_ok() as libc::c_int
|
||||||
return context.set_ui_config(key, value).is_ok() as libc::c_int;
|
|
||||||
}
|
|
||||||
match config::Config::from_str(key) {
|
|
||||||
Ok(key) => context.set_config(key, value).is_ok() as libc::c_int,
|
|
||||||
Err(_) => 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -173,14 +167,7 @@ pub unsafe extern "C" fn dc_get_config(
|
|||||||
let context = &*context;
|
let context = &*context;
|
||||||
|
|
||||||
let key = dc_tools::as_str(key);
|
let key = dc_tools::as_str(key);
|
||||||
if key.starts_with(".ui") {
|
context.get_config_from_str(key).unwrap_or_default().strdup()
|
||||||
return context.get_ui_config(key).unwrap_or_default().strdup();
|
|
||||||
}
|
|
||||||
let key = config::Config::from_str(key).expect("invalid key");
|
|
||||||
|
|
||||||
// TODO: Translating None to NULL would be more sensible than translating None
|
|
||||||
// to "", as it is now.
|
|
||||||
context.get_config(key).unwrap_or_default().strdup()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -550,9 +550,8 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
}
|
}
|
||||||
"get" => {
|
"get" => {
|
||||||
ensure!(!arg1.is_empty(), "Argument <key> missing.");
|
ensure!(!arg1.is_empty(), "Argument <key> missing.");
|
||||||
let key = config::Config::from_str(&arg1)?;
|
let val = context.get_config_from_str(&arg1);
|
||||||
let val = context.get_config(key);
|
println!("{}={:?}", &arg1.to_string(), val);
|
||||||
println!("{}={:?}", key, val);
|
|
||||||
}
|
}
|
||||||
"info" => {
|
"info" => {
|
||||||
println!("{}", to_string(dc_get_info(context)));
|
println!("{}", to_string(dc_get_info(context)));
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
|||||||
configure(&ctx.read().unwrap());
|
configure(&ctx.read().unwrap());
|
||||||
}
|
}
|
||||||
"oauth2" => {
|
"oauth2" => {
|
||||||
if let Some(addr) = ctx.read().unwrap().get_config(config::Config::Addr) {
|
if let Some(addr) = ctx.read().unwrap().get_config(&config::Config::Addr) {
|
||||||
let oauth2_url = dc_get_oauth2_url(
|
let oauth2_url = dc_get_oauth2_url(
|
||||||
&ctx.read().unwrap(),
|
&ctx.read().unwrap(),
|
||||||
&addr,
|
&addr,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use strum::{EnumProperty, IntoEnumIterator};
|
use strum::{EnumProperty, IntoEnumIterator};
|
||||||
use strum_macros::{AsRefStr, Display, EnumIter, EnumProperty, EnumString};
|
use strum_macros::{AsRefStr, Display, EnumIter, EnumProperty, EnumString};
|
||||||
|
|
||||||
@@ -8,9 +10,11 @@ use crate::error::Error;
|
|||||||
use crate::job::*;
|
use crate::job::*;
|
||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
|
|
||||||
|
pub const CONFIG_UI_PREFIX: &str = "ui.";
|
||||||
|
|
||||||
/// The available configuration keys.
|
/// The available configuration keys.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug, Clone, Copy, PartialEq, Eq, Display, EnumString, AsRefStr, EnumIter, EnumProperty,
|
Debug, Clone, PartialEq, Eq, Display, EnumString, AsRefStr, EnumIter, EnumProperty,
|
||||||
)]
|
)]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
pub enum Config {
|
pub enum Config {
|
||||||
@@ -65,11 +69,17 @@ pub enum Config {
|
|||||||
SysMsgsizeMaxRecommended,
|
SysMsgsizeMaxRecommended,
|
||||||
#[strum(serialize = "sys.config_keys")]
|
#[strum(serialize = "sys.config_keys")]
|
||||||
SysConfigKeys,
|
SysConfigKeys,
|
||||||
|
Ui(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
|
|
||||||
|
pub fn get_config_from_str(&self, key: &str) -> Option<String> {
|
||||||
|
self.get_config(&config_from_str(key))
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a configuration key. Returns `None` if no value is set, and no default value found.
|
/// Get a configuration key. Returns `None` if no value is set, and no default value found.
|
||||||
pub fn get_config(&self, key: Config) -> Option<String> {
|
pub fn get_config(&self, key: &Config) -> Option<String> {
|
||||||
let value = match key {
|
let value = match key {
|
||||||
Config::Selfavatar => {
|
Config::Selfavatar => {
|
||||||
let rel_path = self.sql.get_config(self, key);
|
let rel_path = self.sql.get_config(self, key);
|
||||||
@@ -78,6 +88,7 @@ impl Context {
|
|||||||
Config::SysVersion => Some((&*DC_VERSION_STR).clone()),
|
Config::SysVersion => Some((&*DC_VERSION_STR).clone()),
|
||||||
Config::SysMsgsizeMaxRecommended => Some(format!("{}", 24 * 1024 * 1024 / 4 * 3)),
|
Config::SysMsgsizeMaxRecommended => Some(format!("{}", 24 * 1024 * 1024 / 4 * 3)),
|
||||||
Config::SysConfigKeys => Some(get_config_keys_string()),
|
Config::SysConfigKeys => Some(get_config_keys_string()),
|
||||||
|
Config::Ui(key) => self.sql.get_config(self, format!("{}{}", CONFIG_UI_PREFIX, key)),
|
||||||
_ => self.sql.get_config(self, key),
|
_ => self.sql.get_config(self, key),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -92,6 +103,13 @@ impl Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_config_from_str(&self, key: &str, value: Option<&str>) -> Result<(), &str> {
|
||||||
|
if self.sql.set_config(self, config_from_str(key), value).is_err() {
|
||||||
|
return Err("Sql error");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the given config key.
|
/// Set the given config key.
|
||||||
/// If `None` is passed as a value the value is cleared and set to the default if there is one.
|
/// If `None` is passed as a value the value is cleared and set to the default if there is one.
|
||||||
pub fn set_config(&self, key: Config, value: Option<&str>) -> Result<(), Error> {
|
pub fn set_config(&self, key: Config, value: Option<&str>) -> Result<(), Error> {
|
||||||
@@ -125,27 +143,14 @@ impl Context {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.sql.set_config(self, key, val)
|
self.sql.set_config(self, key, val)
|
||||||
}
|
},
|
||||||
|
Config::Ui(key) => {
|
||||||
|
let key = format!("{}{}", CONFIG_UI_PREFIX, key);
|
||||||
|
self.sql.set_config(self, key, value)
|
||||||
|
},
|
||||||
_ => self.sql.set_config(self, key, value),
|
_ => self.sql.set_config(self, key, value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_ui_config(&self, key: &str, value: Option<&str>) -> Result<(), &str> {
|
|
||||||
if !key.starts_with("ui.") {
|
|
||||||
return Err("Ui config key has to be prefixed with 'ui.'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.sql.set_config(self, key, value).is_err() {
|
|
||||||
return Err("Sql error");
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
pub fn get_ui_config(&self, key: &str) -> Option<String> {
|
|
||||||
if key.starts_with("ui.") {
|
|
||||||
return self.sql.get_config(self, key);
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all available configuration keys concated together.
|
/// Returns all available configuration keys concated together.
|
||||||
@@ -159,12 +164,23 @@ fn get_config_keys_string() -> String {
|
|||||||
format!(" {} ", keys)
|
format!(" {} ", keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn config_from_str(key: &str) -> Result<Config, &str> {
|
||||||
|
if key.starts_with(CONFIG_UI_PREFIX) {
|
||||||
|
Config::Ui(key[CONFIG_UI_PREFIX.len()-1..].to_string())
|
||||||
|
} else {
|
||||||
|
if let Ok(config) = Config::from_str(key) {
|
||||||
|
config
|
||||||
|
} else {
|
||||||
|
Err("invalid key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use std::str::FromStr;
|
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
|
use crate::test_utils::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_to_string() {
|
fn test_to_string() {
|
||||||
@@ -182,4 +198,20 @@ mod tests {
|
|||||||
fn test_default_prop() {
|
fn test_default_prop() {
|
||||||
assert_eq!(Config::ImapFolder.get_str("default"), Some("INBOX"));
|
assert_eq!(Config::ImapFolder.get_str("default"), Some("INBOX"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_config_from_str() {
|
||||||
|
assert_eq!(config_from_str("addr"), Config::Addr);
|
||||||
|
assert_eq!(config_from_str("addrxyz"), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_config_from_str() {
|
||||||
|
let t = dummy_context();
|
||||||
|
assert_eq!(t.ctx.set_config_from_str("addr", Some("foo@bar.bar")), Ok(()));
|
||||||
|
assert_eq!(t.ctx.get_config_from_str("addr").unwrap(), "foo@bar.bar");
|
||||||
|
|
||||||
|
assert_eq!(t.ctx.set_config_from_str("ui.desktop.some_string", Some("foobar")), Ok(()));
|
||||||
|
assert_eq!(t.ctx.get_config_from_str("ui.desktop.some_string").unwrap(), "foobar");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ impl Contact {
|
|||||||
name: context.stock_str(StockMessage::SelfMsg).into(),
|
name: context.stock_str(StockMessage::SelfMsg).into(),
|
||||||
authname: "".into(),
|
authname: "".into(),
|
||||||
addr: context
|
addr: context
|
||||||
.get_config(Config::ConfiguredAddr)
|
.get_config(&Config::ConfiguredAddr)
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
blocked: false,
|
blocked: false,
|
||||||
origin: Origin::Unknown,
|
origin: Origin::Unknown,
|
||||||
@@ -257,7 +257,7 @@ impl Contact {
|
|||||||
|
|
||||||
let addr_normalized = addr_normalize(addr.as_ref());
|
let addr_normalized = addr_normalize(addr.as_ref());
|
||||||
let addr_self = context
|
let addr_self = context
|
||||||
.get_config(Config::ConfiguredAddr)
|
.get_config(&Config::ConfiguredAddr)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
if addr_normalized == addr_self {
|
if addr_normalized == addr_self {
|
||||||
@@ -295,7 +295,7 @@ impl Contact {
|
|||||||
|
|
||||||
let addr = addr_normalize(addr.as_ref());
|
let addr = addr_normalize(addr.as_ref());
|
||||||
let addr_self = context
|
let addr_self = context
|
||||||
.get_config(Config::ConfiguredAddr)
|
.get_config(&Config::ConfiguredAddr)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
if addr == addr_self {
|
if addr == addr_self {
|
||||||
@@ -456,7 +456,7 @@ impl Contact {
|
|||||||
query: Option<impl AsRef<str>>,
|
query: Option<impl AsRef<str>>,
|
||||||
) -> Result<Vec<u32>> {
|
) -> Result<Vec<u32>> {
|
||||||
let self_addr = context
|
let self_addr = context
|
||||||
.get_config(Config::ConfiguredAddr)
|
.get_config(&Config::ConfiguredAddr)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let mut add_self = false;
|
let mut add_self = false;
|
||||||
@@ -499,7 +499,7 @@ impl Contact {
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let self_name = context.get_config(Config::Displayname).unwrap_or_default();
|
let self_name = context.get_config(&Config::Displayname).unwrap_or_default();
|
||||||
let self_name2 = context.stock_str(StockMessage::SelfMsg);
|
let self_name2 = context.stock_str(StockMessage::SelfMsg);
|
||||||
|
|
||||||
if let Some(query) = query {
|
if let Some(query) = query {
|
||||||
@@ -765,7 +765,7 @@ impl Contact {
|
|||||||
/// using dc_set_config(context, "selfavatar", image).
|
/// using dc_set_config(context, "selfavatar", image).
|
||||||
pub fn get_profile_image(&self, context: &Context) -> Option<PathBuf> {
|
pub fn get_profile_image(&self, context: &Context) -> Option<PathBuf> {
|
||||||
if self.id == DC_CONTACT_ID_SELF {
|
if self.id == DC_CONTACT_ID_SELF {
|
||||||
if let Some(p) = context.get_config(Config::Selfavatar) {
|
if let Some(p) = context.get_config(&Config::Selfavatar) {
|
||||||
return Some(PathBuf::from(p));
|
return Some(PathBuf::from(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1026,7 +1026,7 @@ pub fn addr_cmp(addr1: impl AsRef<str>, addr2: impl AsRef<str>) -> bool {
|
|||||||
pub fn addr_equals_self(context: &Context, addr: impl AsRef<str>) -> bool {
|
pub fn addr_equals_self(context: &Context, addr: impl AsRef<str>) -> bool {
|
||||||
if !addr.as_ref().is_empty() {
|
if !addr.as_ref().is_empty() {
|
||||||
let normalized_addr = addr_normalize(addr.as_ref());
|
let normalized_addr = addr_normalize(addr.as_ref());
|
||||||
if let Some(self_addr) = context.get_config(Config::ConfiguredAddr) {
|
if let Some(self_addr) = context.get_config(&Config::ConfiguredAddr) {
|
||||||
return normalized_addr == self_addr;
|
return normalized_addr == self_addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1025,7 +1025,7 @@ unsafe fn contains_report(mime: *mut mailmime) -> bool {
|
|||||||
/// [Config::ConfiguredAddr] is configured, this address is returned.
|
/// [Config::ConfiguredAddr] is configured, this address is returned.
|
||||||
pub fn ensure_secret_key_exists(context: &Context) -> Result<String> {
|
pub fn ensure_secret_key_exists(context: &Context) -> Result<String> {
|
||||||
let self_addr = context
|
let self_addr = context
|
||||||
.get_config(Config::ConfiguredAddr)
|
.get_config(&Config::ConfiguredAddr)
|
||||||
.ok_or(format_err!(concat!(
|
.ok_or(format_err!(concat!(
|
||||||
"Failed to get self address, ",
|
"Failed to get self address, ",
|
||||||
"cannot ensure secret key if not configured."
|
"cannot ensure secret key if not configured."
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ unsafe fn stress_functions(context: &Context) {
|
|||||||
free(fn1 as *mut libc::c_void);
|
free(fn1 as *mut libc::c_void);
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = context.get_config(config::Config::SysConfigKeys).unwrap();
|
let res = context.get_config(&config::Config::SysConfigKeys).unwrap();
|
||||||
|
|
||||||
assert!(!res.contains(" probably_never_a_key "));
|
assert!(!res.contains(" probably_never_a_key "));
|
||||||
assert!(res.contains(" addr "));
|
assert!(res.contains(" addr "));
|
||||||
|
|||||||
Reference in New Issue
Block a user