diff options
Diffstat (limited to 'components/config/prefs.rs')
-rw-r--r-- | components/config/prefs.rs | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/components/config/prefs.rs b/components/config/prefs.rs index 10e824241e1..e5ec7c3aeec 100644 --- a/components/config/prefs.rs +++ b/components/config/prefs.rs @@ -4,10 +4,12 @@ use std::borrow::ToOwned; use std::collections::HashMap; +use std::convert::{TryFrom, TryInto}; use embedder_traits::resources::{self, Resource}; use gen::Prefs; use lazy_static::lazy_static; +use log::warn; use serde_json::{self, Value}; use crate::pref_util::Preferences; @@ -17,7 +19,11 @@ lazy_static! { static ref PREFS: Preferences<'static, Prefs> = { let def_prefs: Prefs = serde_json::from_str(&resources::read_string(Resource::Preferences)) .expect("Failed to initialize config preferences."); - Preferences::new(def_prefs, &gen::PREF_ACCESSORS) + let result = Preferences::new(def_prefs, &gen::PREF_ACCESSORS); + for (key, value) in result.iter() { + set_stylo_pref_ref(&key, &value); + } + result }; } @@ -38,9 +44,11 @@ macro_rules! pref { #[macro_export] macro_rules! set_pref { ($($segment: ident).+, $value: expr) => {{ + let value = $value; + $crate::prefs::set_stylo_pref(stringify!($($segment).+), value); let values = $crate::prefs::pref_map().values(); let mut lock = values.write().unwrap(); - lock$ (.$segment)+ = $value; + lock$ (.$segment)+ = value; }}; } @@ -56,11 +64,62 @@ pub fn pref_map() -> &'static Preferences<'static, Prefs> { } pub fn add_user_prefs(prefs: HashMap<String, PrefValue>) { + for (key, value) in prefs.iter() { + set_stylo_pref_ref(key, value); + } if let Err(error) = PREFS.set_all(prefs.into_iter()) { panic!("Error setting preference: {:?}", error); } } +pub fn set_stylo_pref(key: &str, value: impl Into<PrefValue>) { + set_stylo_pref_ref(key, &value.into()); +} + +fn set_stylo_pref_ref(key: &str, value: &PrefValue) { + match value.try_into() { + Ok(StyloPrefValue::Bool(value)) => style_config::set_bool(key, value), + Ok(StyloPrefValue::Int(value)) => style_config::set_i32(key, value), + Err(TryFromPrefValueError::IntegerOverflow(value)) => { + // TODO: logging doesn’t actually work this early, so we should + // split PrefValue into i32 and i64 variants. + warn!("Pref value too big for Stylo: {} ({})", key, value); + }, + Err(TryFromPrefValueError::UnmappedType) => { + // Most of Servo’s prefs will hit this. When adding a new pref type + // in Stylo, update TryFrom<&PrefValue> for StyloPrefValue as well. + }, + } +} + +enum StyloPrefValue { + Bool(bool), + Int(i32), +} + +enum TryFromPrefValueError { + IntegerOverflow(i64), + UnmappedType, +} + +impl TryFrom<&PrefValue> for StyloPrefValue { + type Error = TryFromPrefValueError; + + fn try_from(value: &PrefValue) -> Result<Self, Self::Error> { + match value { + &PrefValue::Int(value) => { + if let Ok(value) = value.try_into() { + Ok(Self::Int(value)) + } else { + Err(TryFromPrefValueError::IntegerOverflow(value)) + } + }, + &PrefValue::Bool(value) => Ok(Self::Bool(value)), + _ => Err(TryFromPrefValueError::UnmappedType), + } + } +} + pub fn read_prefs_map(txt: &str) -> Result<HashMap<String, PrefValue>, PrefError> { let prefs: HashMap<String, Value> = serde_json::from_str(txt).map_err(|e| PrefError::JsonParseErr(e))?; |