mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
* Allow settings userscripts through preferences Signed-off-by: Tony <legendmastertony@gmail.com> * mach fmt instead of cargo fmt Signed-off-by: Tony <legendmastertony@gmail.com> * Fix pref loading not working for array values Signed-off-by: Tony <legendmastertony@gmail.com> * Use pref! in userscripts instead Signed-off-by: Tony <legendmastertony@gmail.com> * Implement the model jdm suggested - Remove userscripts from all places and move it to servoshell - Add in `UserContentManager` struct and passing it through `Servo::new` all the way down to script thread Signed-off-by: Tony <legendmastertony@gmail.com> * Apply suggestions from code review and format Signed-off-by: Tony <legendmastertony@gmail.com> * Revert unrelated change Signed-off-by: Tony <legendmastertony@gmail.com> --------- Signed-off-by: Tony <legendmastertony@gmail.com> Signed-off-by: Tony <68118705+Legend-Master@users.noreply.github.com>
149 lines
4.4 KiB
Rust
149 lines
4.4 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_json::Value;
|
|
|
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
|
pub enum PrefValue {
|
|
Float(f64),
|
|
Int(i64),
|
|
Str(String),
|
|
Bool(bool),
|
|
Array(Vec<PrefValue>),
|
|
}
|
|
|
|
impl PrefValue {
|
|
pub fn from_booleanish_str(input: &str) -> Self {
|
|
match input {
|
|
"false" => PrefValue::Bool(false),
|
|
"true" => PrefValue::Bool(true),
|
|
_ => input
|
|
.parse::<i64>()
|
|
.map(PrefValue::Int)
|
|
.or_else(|_| input.parse::<f64>().map(PrefValue::Float))
|
|
.unwrap_or_else(|_| PrefValue::from(input)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TryFrom<&Value> for PrefValue {
|
|
type Error = String;
|
|
|
|
fn try_from(value: &Value) -> Result<Self, Self::Error> {
|
|
match value {
|
|
Value::Null => Err("Cannot turn null into preference".into()),
|
|
Value::Bool(value) => Ok((*value).into()),
|
|
Value::Number(number) => number
|
|
.as_i64()
|
|
.map(Into::into)
|
|
.or_else(|| number.as_f64().map(Into::into))
|
|
.map(Ok)
|
|
.unwrap_or(Err("Could not parse number from JSON".into())),
|
|
Value::String(value) => Ok(value.clone().into()),
|
|
Value::Array(array) => {
|
|
let array = array
|
|
.iter()
|
|
.map(TryInto::<PrefValue>::try_into)
|
|
.collect::<Result<Vec<_>, _>>()?;
|
|
Ok(PrefValue::Array(array))
|
|
},
|
|
Value::Object(_) => Err("Cannot turn object into preference".into()),
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_pref_from {
|
|
($($t: ty => $variant: path,)*) => {
|
|
$(
|
|
impl From<$t> for PrefValue {
|
|
fn from(other: $t) -> Self {
|
|
$variant(other.into())
|
|
}
|
|
}
|
|
)+
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_from_pref {
|
|
($($variant: path => $t: ty,)*) => {
|
|
$(
|
|
impl TryFrom<PrefValue> for $t {
|
|
type Error = String;
|
|
fn try_from(other: PrefValue) -> Result<Self, Self::Error> {
|
|
match other {
|
|
$variant(value) => Ok(value.into()),
|
|
_ => Err(format!("Cannot convert {other:?} to {}", std::any::type_name::<$t>())),
|
|
}
|
|
}
|
|
}
|
|
)+
|
|
}
|
|
}
|
|
|
|
impl_pref_from! {
|
|
f64 => PrefValue::Float,
|
|
i64 => PrefValue::Int,
|
|
String => PrefValue::Str,
|
|
&str => PrefValue::Str,
|
|
bool => PrefValue::Bool,
|
|
}
|
|
|
|
impl_from_pref! {
|
|
PrefValue::Float => f64,
|
|
PrefValue::Int => i64,
|
|
PrefValue::Str => String,
|
|
PrefValue::Bool => bool,
|
|
}
|
|
|
|
impl From<[f64; 4]> for PrefValue {
|
|
fn from(other: [f64; 4]) -> PrefValue {
|
|
PrefValue::Array(IntoIterator::into_iter(other).map(|v| v.into()).collect())
|
|
}
|
|
}
|
|
|
|
impl From<PrefValue> for [f64; 4] {
|
|
fn from(other: PrefValue) -> [f64; 4] {
|
|
match other {
|
|
PrefValue::Array(values) if values.len() == 4 => {
|
|
let values: Vec<f64> = values
|
|
.into_iter()
|
|
.map(TryFrom::try_from)
|
|
.filter_map(Result::ok)
|
|
.collect();
|
|
if values.len() == 4 {
|
|
[values[0], values[1], values[2], values[3]]
|
|
} else {
|
|
panic!(
|
|
"Cannot convert PrefValue to {:?}",
|
|
std::any::type_name::<[f64; 4]>()
|
|
)
|
|
}
|
|
},
|
|
_ => panic!(
|
|
"Cannot convert {:?} to {:?}",
|
|
other,
|
|
std::any::type_name::<[f64; 4]>()
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_pref_value_from_str() {
|
|
let value = PrefValue::from_booleanish_str("21");
|
|
assert_eq!(value, PrefValue::Int(21));
|
|
|
|
let value = PrefValue::from_booleanish_str("12.5");
|
|
assert_eq!(value, PrefValue::Float(12.5));
|
|
|
|
let value = PrefValue::from_booleanish_str("a string");
|
|
assert_eq!(value, PrefValue::Str("a string".into()));
|
|
|
|
let value = PrefValue::from_booleanish_str("false");
|
|
assert_eq!(value, PrefValue::Bool(false));
|
|
|
|
let value = PrefValue::from_booleanish_str("true");
|
|
assert_eq!(value, PrefValue::Bool(true));
|
|
}
|