style_traits/specified_value_info.rs
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Value information for devtools.
6
7use crate::arc_slice::ArcSlice;
8use crate::owned_slice::OwnedSlice;
9use servo_arc::Arc;
10use std::ops::Range;
11use std::sync::Arc as StdArc;
12use thin_vec::ThinVec;
13
14/// Type of value that a property supports. This is used by Gecko's
15/// devtools to make sense about value it parses, and types listed
16/// here should match InspectorPropertyType in InspectorUtils.webidl.
17///
18/// XXX This should really be a bitflags rather than a namespace mod,
19/// but currently we cannot use bitflags in const.
20#[allow(non_snake_case)]
21pub mod CssType {
22 /// <color>
23 pub const COLOR: u8 = 1 << 0;
24 /// <gradient>
25 pub const GRADIENT: u8 = 1 << 1;
26 /// <timing-function>
27 pub const TIMING_FUNCTION: u8 = 1 << 2;
28}
29
30/// See SpecifiedValueInfo::collect_completion_keywords.
31pub type KeywordsCollectFn<'a> = &'a mut dyn FnMut(&[&'static str]);
32
33/// Information of values of a given specified value type.
34///
35/// This trait is derivable with `#[derive(SpecifiedValueInfo)]`.
36///
37/// The algorithm traverses the type definition. For `SUPPORTED_TYPES`,
38/// it puts an or'ed value of `SUPPORTED_TYPES` of all types it finds.
39/// For `collect_completion_keywords`, it recursively invokes this
40/// method on types found, and lists all keyword values and function
41/// names following the same rule as `ToCss` in that method.
42///
43/// Some attributes of `ToCss` can affect the behavior, specifically:
44/// * If `#[css(function)]` is found, the content inside the annotated
45/// variant (or the whole type) isn't traversed, only the function
46/// name is listed in `collect_completion_keywords`.
47/// * If `#[css(skip)]` is found, the content inside the variant or
48/// field is ignored.
49/// * Values listed in `#[css(if_empty)]`, `#[parse(aliases)]`, and
50/// `#[css(keyword)]` are added into `collect_completion_keywords`.
51///
52/// In addition to `css` attributes, it also has `value_info` helper
53/// attributes, including:
54/// * `#[value_info(ty = "TYPE")]` can be used to specify a constant
55/// from `CssType` to `SUPPORTED_TYPES`.
56/// * `#[value_info(other_values = "value1,value2")]` can be used to
57/// add other values related to a field, variant, or the type itself
58/// into `collect_completion_keywords`.
59/// * `#[value_info(starts_with_keyword)]` can be used on variants to
60/// add the name of a non-unit variant (serialized like `ToCss`) into
61/// `collect_completion_keywords`.
62/// * `#[value_info(skip)]` ignores the variant (can be useful for functions where you don't want
63/// the argument to show up in the value-info output).
64pub trait SpecifiedValueInfo {
65 /// Supported CssTypes by the given value type.
66 ///
67 /// XXX This should be typed CssType when that becomes a bitflags.
68 /// Currently we cannot do so since bitflags cannot be used in constant.
69 const SUPPORTED_TYPES: u8 = 0;
70
71 /// Collect value starting words for the given specified value type.
72 /// This includes keyword and function names which can appear at the
73 /// beginning of a value of this type.
74 ///
75 /// Caller should pass in a callback function to accept the list of
76 /// values. The callback function can be called multiple times, and
77 /// some values passed to the callback may be duplicate.
78 fn collect_completion_keywords(_f: KeywordsCollectFn) {}
79}
80
81impl SpecifiedValueInfo for bool {}
82impl SpecifiedValueInfo for f32 {}
83impl SpecifiedValueInfo for i8 {}
84impl SpecifiedValueInfo for i32 {}
85impl SpecifiedValueInfo for u8 {}
86impl SpecifiedValueInfo for u16 {}
87impl SpecifiedValueInfo for u32 {}
88impl SpecifiedValueInfo for usize {}
89impl SpecifiedValueInfo for str {}
90impl SpecifiedValueInfo for String {}
91impl SpecifiedValueInfo for crate::owned_str::OwnedStr {}
92
93#[cfg(feature = "servo")]
94impl SpecifiedValueInfo for ::stylo_atoms::Atom {}
95#[cfg(feature = "servo")]
96impl SpecifiedValueInfo for ::url::Url {}
97
98impl<T: SpecifiedValueInfo + ?Sized> SpecifiedValueInfo for Box<T> {
99 const SUPPORTED_TYPES: u8 = T::SUPPORTED_TYPES;
100 fn collect_completion_keywords(f: KeywordsCollectFn) {
101 T::collect_completion_keywords(f);
102 }
103}
104
105impl<T: SpecifiedValueInfo> SpecifiedValueInfo for [T] {
106 const SUPPORTED_TYPES: u8 = T::SUPPORTED_TYPES;
107 fn collect_completion_keywords(f: KeywordsCollectFn) {
108 T::collect_completion_keywords(f);
109 }
110}
111
112macro_rules! impl_generic_specified_value_info {
113 ($ty:ident<$param:ident>) => {
114 impl<$param: SpecifiedValueInfo> SpecifiedValueInfo for $ty<$param> {
115 const SUPPORTED_TYPES: u8 = $param::SUPPORTED_TYPES;
116 fn collect_completion_keywords(f: KeywordsCollectFn) {
117 $param::collect_completion_keywords(f);
118 }
119 }
120 };
121}
122impl_generic_specified_value_info!(Option<T>);
123impl_generic_specified_value_info!(OwnedSlice<T>);
124impl_generic_specified_value_info!(Vec<T>);
125impl_generic_specified_value_info!(ThinVec<T>);
126impl_generic_specified_value_info!(Arc<T>);
127impl_generic_specified_value_info!(StdArc<T>);
128impl_generic_specified_value_info!(ArcSlice<T>);
129impl_generic_specified_value_info!(Range<Idx>);
130
131impl<T1, T2> SpecifiedValueInfo for (T1, T2)
132where
133 T1: SpecifiedValueInfo,
134 T2: SpecifiedValueInfo,
135{
136 const SUPPORTED_TYPES: u8 = T1::SUPPORTED_TYPES | T2::SUPPORTED_TYPES;
137
138 fn collect_completion_keywords(f: KeywordsCollectFn) {
139 T1::collect_completion_keywords(f);
140 T2::collect_completion_keywords(f);
141 }
142}