diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-01-14 14:54:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-14 13:54:06 +0000 |
commit | 0e616e0c5d2bef8a6de1df25f2419a435837ed63 (patch) | |
tree | 71a3c54941f8283e58b5d6477f6b0a9aebe044d9 /components/config/macro | |
parent | c4c85affb50419af4b70c42fcb1f03dea3527044 (diff) | |
download | servo-0e616e0c5d2bef8a6de1df25f2419a435837ed63.tar.gz servo-0e616e0c5d2bef8a6de1df25f2419a435837ed63.zip |
api: Flatten and simplify Servo preferences (#34966)
Flatten and simplify Servo's preferences code. In addition, have both
preferences and options passed in as arguments to `Servo::new()` and
make sure not to use the globally set preferences in `servoshell` (as
much as possible now).
Instead of a complex procedural macro to generate preferences, just
expose a very simple derive macro that adds string based getters and
setters.
- All command-line parsing is moved to servoshell.
- There is no longer the concept of a missing preference.
- Preferences no longer have to be part of the resources bundle because
they now have reasonable default values.
- servoshell specific preferences are no longer part of the preferences
exposed by the Servo API.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/config/macro')
-rw-r--r-- | components/config/macro/Cargo.toml | 19 | ||||
-rw-r--r-- | components/config/macro/lib.rs | 55 |
2 files changed, 74 insertions, 0 deletions
diff --git a/components/config/macro/Cargo.toml b/components/config/macro/Cargo.toml new file mode 100644 index 00000000000..17ff88fbe9f --- /dev/null +++ b/components/config/macro/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "servo_config_macro" +version.workspace = true +authors.workspace = true +license.workspace = true +edition.workspace = true +publish.workspace = true +rust-version.workspace = true + +[lib] +name = "servo_config_macro" +proc-macro = true +path = "lib.rs" + +[dependencies] +proc-macro2 = { workspace = true } +quote = { workspace = true } +syn = { workspace = true } +synstructure = { workspace = true } diff --git a/components/config/macro/lib.rs b/components/config/macro/lib.rs new file mode 100644 index 00000000000..da5d3635bc8 --- /dev/null +++ b/components/config/macro/lib.rs @@ -0,0 +1,55 @@ +/* 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 proc_macro2::TokenStream; +use quote::quote; +use syn::{Data, Fields}; +use synstructure::decl_derive; + +decl_derive!([ServoPreferences] => servo_preferences_derive); + +/// A derive macro that adds string-based getter and setter for each field of this struct +/// (enums and other types are not supported). Each field must be able to be convertable +/// (with `into()`) into a `PrefValue`. +fn servo_preferences_derive(input: synstructure::Structure) -> TokenStream { + let ast = input.ast(); + + let Data::Struct(ref data) = ast.data else { + unimplemented!(); + }; + let Fields::Named(ref named_fields) = data.fields else { + unimplemented!() + }; + + let mut get_match_cases = quote!(); + for field in named_fields.named.iter() { + let name = field.ident.as_ref().unwrap(); + get_match_cases.extend(quote!(stringify!(#name) => self.#name.clone().into(),)) + } + + let mut set_match_cases = quote!(); + for field in named_fields.named.iter() { + let name = field.ident.as_ref().unwrap(); + set_match_cases.extend(quote!(stringify!(#name) => self.#name = value.try_into().unwrap(),)) + } + + let structure_name = &ast.ident; + quote! { + impl #structure_name { + pub fn get_value(&self, name: &str) -> PrefValue { + match name { + #get_match_cases + _ => { panic!("Unknown preference: {:?}", name); } + } + } + + pub fn set_value(&mut self, name: &str, value: PrefValue) { + match name { + #set_match_cases + _ => { panic!("Unknown preference: {:?}", name); } + } + } + } + } +} |