diff options
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r-- | components/script/dom/bindings/callback.rs | 2 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 101 | ||||
-rw-r--r-- | components/script/dom/bindings/global.rs | 47 | ||||
-rw-r--r-- | components/script/dom/bindings/guard.rs | 55 | ||||
-rw-r--r-- | components/script/dom/bindings/interface.rs | 100 | ||||
-rw-r--r-- | components/script/dom/bindings/mod.rs | 1 | ||||
-rw-r--r-- | components/script/dom/bindings/utils.rs | 31 |
7 files changed, 169 insertions, 168 deletions
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs index e5168e57768..c9424adf5b2 100644 --- a/components/script/dom/bindings/callback.rs +++ b/components/script/dom/bindings/callback.rs @@ -164,7 +164,7 @@ impl CallSetup { /// Performs the setup needed to make a call. #[allow(unrooted_must_root)] pub fn new<T: CallbackContainer>(callback: &T, handling: ExceptionHandling) -> CallSetup { - let global = global_root_from_object(callback.callback()); + let global = unsafe { global_root_from_object(callback.callback()) }; let cx = global.r().get_cx(); let exception_compartment = unsafe { diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index b44cf2c1c2b..73d9f7f3ed0 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -5,6 +5,7 @@ # Common codegen classes. from collections import defaultdict +from itertools import groupby import operator import re @@ -1322,31 +1323,23 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): returnType) -class MemberCondition: +def MemberCondition(pref, func): """ - An object representing the condition for a member to actually be - exposed. Any of the arguments can be None. If not - None, they should have the following types: + A string representing the condition for a member to actually be exposed. + Any of the arguments can be None. If not None, they should have the + following types: pref: The name of the preference. func: The name of the function. """ - def __init__(self, pref=None, func=None): - assert pref is None or isinstance(pref, str) - assert func is None or isinstance(func, str) - self.pref = pref - - def toFuncPtr(val): - if val is None: - return "None" - return "Some(%s)" % val - self.func = toFuncPtr(func) - - def __eq__(self, other): - return (self.pref == other.pref and self.func == other.func) - - def __ne__(self, other): - return not self.__eq__(other) + assert pref is None or isinstance(pref, str) + assert func is None or isinstance(func, str) + assert func is None or pref is None + if pref: + return 'Condition::Pref("%s")' % pref + if func: + return 'Condition::Func(%s)' % func + return "Condition::Satisfied" class PropertyDefiner: @@ -1390,8 +1383,8 @@ class PropertyDefiner: PropertyDefiner.getStringAttr(interfaceMember, "Func")) - def generatePrefableArray(self, array, name, specTemplate, specTerminator, - specType, getCondition, getDataTuple): + def generateGuardedArray(self, array, name, specTemplate, specTerminator, + specType, getCondition, getDataTuple): """ This method generates our various arrays. @@ -1417,43 +1410,23 @@ class PropertyDefiner: # members while still allowing us to define all the members in the smallest # number of JSAPI calls. assert len(array) != 0 - # So we won't put a specTerminator at the very front of the list: - lastCondition = getCondition(array[0], self.descriptor) specs = [] - currentSpecs = [] prefableSpecs = [] + prefableTemplate = ' Guard::new(%s, %s[%d])' - prefableTemplate = ' Prefable { pref: %s, specs: %s[%d], terminator: %s }' - - def switchToCondition(props, condition): - prefableSpecs.append(prefableTemplate % - ('Some("%s")' % condition.pref if condition.pref else 'None', - name + "_specs", - len(specs), - 'true' if specTerminator else 'false')) + for cond, members in groupby(array, lambda m: getCondition(m, self.descriptor)): + currentSpecs = [specTemplate % getDataTuple(m) for m in members] + if specTerminator: + currentSpecs.append(specTerminator) specs.append("&[\n" + ",\n".join(currentSpecs) + "]\n") - del currentSpecs[:] - - for member in array: - curCondition = getCondition(member, self.descriptor) - if lastCondition != curCondition: - # Terminate previous list - if specTerminator: - currentSpecs.append(specTerminator) - # And switch to our new pref - switchToCondition(self, lastCondition) - lastCondition = curCondition - # And the actual spec - currentSpecs.append(specTemplate % getDataTuple(member)) - if specTerminator: - currentSpecs.append(specTerminator) - switchToCondition(self, lastCondition) + prefableSpecs.append( + prefableTemplate % (cond, name + "_specs", len(specs) - 1)) specsArray = ("const %s_specs: &'static [&'static[%s]] = &[\n" + ",\n".join(specs) + "\n" + "];\n") % (name, specType) - prefArray = ("const %s: &'static [Prefable<%s>] = &[\n" + + prefArray = ("const %s: &'static [Guard<&'static [%s]>] = &[\n" + ",\n".join(prefableSpecs) + "\n" + "];\n") % (name, specType) return specsArray + prefArray @@ -1500,7 +1473,7 @@ class MethodDefiner(PropertyDefiner): "methodInfo": False, "selfHostedName": "ArrayValues", "length": 0, - "condition": MemberCondition()}) + "condition": "Condition::Satisfied"}) isUnforgeableInterface = bool(descriptor.interface.getExtendedAttribute("Unforgeable")) if not static and unforgeable == isUnforgeableInterface: @@ -1551,7 +1524,7 @@ class MethodDefiner(PropertyDefiner): % m["name"][2:], accessor, jitinfo, m["length"], flags, selfHostedName) return (str_to_const_array(m["name"]), accessor, jitinfo, m["length"], flags, selfHostedName) - return self.generatePrefableArray( + return self.generateGuardedArray( array, name, ' JSFunctionSpec {\n' ' name: %s as *const u8 as *const libc::c_char,\n' @@ -1631,7 +1604,7 @@ class AttrDefiner(PropertyDefiner): return (str_to_const_array(attr.identifier.name), flags, getter(attr), setter(attr)) - return self.generatePrefableArray( + return self.generateGuardedArray( array, name, ' JSPropertySpec {\n' ' name: %s as *const u8 as *const libc::c_char,\n' @@ -1666,7 +1639,7 @@ class ConstDefiner(PropertyDefiner): return (str_to_const_array(const.identifier.name), convertConstIDLValueToJSVal(const.value)) - return self.generatePrefableArray( + return self.generateGuardedArray( array, name, ' ConstantSpec { name: %s, value: %s }', None, @@ -2327,8 +2300,8 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties): """ unforgeables = [] - defineUnforgeableAttrs = "define_prefable_properties(cx, unforgeable_holder.handle(), %s);" - defineUnforgeableMethods = "define_prefable_methods(cx, unforgeable_holder.handle(), %s);" + defineUnforgeableAttrs = "define_guarded_properties(cx, unforgeable_holder.handle(), %s);" + defineUnforgeableMethods = "define_guarded_methods(cx, unforgeable_holder.handle(), %s);" unforgeableMembers = [ (defineUnforgeableAttrs, properties.unforgeable_attrs), @@ -2560,15 +2533,10 @@ assert!(!prototype_proto.ptr.is_null());""" % getPrototypeProto)] properties = {"id": name} for arrayName in self.properties.arrayNames(): array = getattr(self.properties, arrayName) - if arrayName == "consts": - if array.length(): - properties[arrayName] = array.variableName() - else: - properties[arrayName] = "&[]" - elif array.length(): - properties[arrayName] = "Some(%s)" % array.variableName() + if array.length(): + properties[arrayName] = array.variableName() else: - properties[arrayName] = "None" + properties[arrayName] = "&[]" code.append(CGGeneric(""" let mut prototype = RootedObject::new(cx, ptr::null_mut()); @@ -5563,13 +5531,13 @@ class CGBindingRoot(CGThing): 'dom::bindings::interface::{InterfaceConstructorBehavior, NonCallbackInterfaceObjectClass}', 'dom::bindings::interface::{create_callback_interface_object, create_interface_prototype_object}', 'dom::bindings::interface::{create_named_constructors, create_noncallback_interface_object}', - 'dom::bindings::interface::{define_prefable_methods, define_prefable_properties}', + 'dom::bindings::interface::{define_guarded_methods, define_guarded_properties}', 'dom::bindings::interface::{ConstantSpec, NonNullJSNative}', 'dom::bindings::interface::ConstantVal::{IntVal, UintVal}', 'dom::bindings::js::{JS, Root, RootedReference}', 'dom::bindings::js::{OptionalRootedReference}', 'dom::bindings::reflector::{Reflectable}', - 'dom::bindings::utils::{DOMClass, DOMJSClass, Prefable}', + 'dom::bindings::utils::{DOMClass, DOMJSClass}', 'dom::bindings::utils::{DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, JSCLASS_DOM_GLOBAL}', 'dom::bindings::utils::{ProtoOrIfaceArray, create_dom_global}', 'dom::bindings::utils::{enumerate_global, finalize_global, find_enum_string_index}', @@ -5593,6 +5561,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::error::{Fallible, Error, ErrorResult}', 'dom::bindings::error::Error::JSFailed', 'dom::bindings::error::throw_dom_exception', + 'dom::bindings::guard::{Condition, Guard}', 'dom::bindings::proxyhandler', 'dom::bindings::proxyhandler::{ensure_expando_object, fill_property_descriptor}', 'dom::bindings::proxyhandler::{get_expando_object, get_property_descriptor}', diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index ff36817b660..036c53e67b4 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -302,44 +302,39 @@ impl GlobalRoot { /// Returns the global object of the realm that the given DOM object's reflector was created in. pub fn global_root_from_reflector<T: Reflectable>(reflector: &T) -> GlobalRoot { - global_root_from_object(*reflector.reflector().get_jsobject()) + unsafe { global_root_from_object(*reflector.reflector().get_jsobject()) } } /// Returns the Rust global object from a JS global object. #[allow(unrooted_must_root)] -pub fn global_root_from_global(global: *mut JSObject) -> GlobalRoot { - unsafe { - let clasp = JS_GetClass(global); - assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0); - match root_from_object(global) { - Ok(window) => return GlobalRoot::Window(window), - Err(_) => (), - } - - match root_from_object(global) { - Ok(worker) => return GlobalRoot::Worker(worker), - Err(_) => (), - } +unsafe fn global_root_from_global(global: *mut JSObject) -> GlobalRoot { + assert!(!global.is_null()); + let clasp = JS_GetClass(global); + assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0); + match root_from_object(global) { + Ok(window) => return GlobalRoot::Window(window), + Err(_) => (), + } - panic!("found DOM global that doesn't unwrap to Window or WorkerGlobalScope") + match root_from_object(global) { + Ok(worker) => return GlobalRoot::Worker(worker), + Err(_) => (), } + + panic!("found DOM global that doesn't unwrap to Window or WorkerGlobalScope") } /// Returns the global object of the realm that the given JS object was created in. #[allow(unrooted_must_root)] -pub fn global_root_from_object(obj: *mut JSObject) -> GlobalRoot { - unsafe { - let global = GetGlobalForObjectCrossCompartment(obj); - global_root_from_global(global) - } +pub unsafe fn global_root_from_object(obj: *mut JSObject) -> GlobalRoot { + assert!(!obj.is_null()); + let global = GetGlobalForObjectCrossCompartment(obj); + global_root_from_global(global) } /// Returns the global object for the given JSContext #[allow(unrooted_must_root)] -pub fn global_root_from_context(cx: *mut JSContext) -> GlobalRoot { - unsafe { - let global = CurrentGlobalOrNull(cx); - assert!(!global.is_null()); - global_root_from_global(global) - } +pub unsafe fn global_root_from_context(cx: *mut JSContext) -> GlobalRoot { + let global = CurrentGlobalOrNull(cx); + global_root_from_global(global) } diff --git a/components/script/dom/bindings/guard.rs b/components/script/dom/bindings/guard.rs new file mode 100644 index 00000000000..40faebbd4f2 --- /dev/null +++ b/components/script/dom/bindings/guard.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 http://mozilla.org/MPL/2.0/. */ + +//! Machinery to conditionally expose things. + +use js::jsapi::{HandleObject, JSContext}; +use util::prefs::get_pref; + +/// A container with a condition. +pub struct Guard<T: Clone + Copy> { + condition: Condition, + value: T, +} + +impl<T: Clone + Copy> Guard<T> { + /// Construct a new guarded value. + pub const fn new(condition: Condition, value: T) -> Self { + Guard { + condition: condition, + value: value, + } + } + + /// Expose the value if the condition is satisfied. + /// + /// The passed handle is the object on which the value may be exposed. + pub unsafe fn expose(&self, cx: *mut JSContext, obj: HandleObject) -> Option<T> { + if self.condition.is_satisfied(cx, obj) { + Some(self.value) + } else { + None + } + } +} + +/// A condition to expose things. +pub enum Condition { + /// The condition is satisfied if the function returns true. + Func(unsafe fn(*mut JSContext, HandleObject) -> bool), + /// The condition is satisfied if the preference is set. + Pref(&'static str), + /// The condition is always satisfied. + Satisfied, +} + +impl Condition { + unsafe fn is_satisfied(&self, cx: *mut JSContext, obj: HandleObject) -> bool { + match *self { + Condition::Pref(name) => get_pref(name).as_boolean().unwrap_or(false), + Condition::Func(f) => f(cx, obj), + Condition::Satisfied => true, + } + } +} diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index 9ce31b8bd36..590e57ba8e0 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -6,7 +6,8 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::conversions::get_dom_class; -use dom::bindings::utils::{get_proto_or_iface_array, Prefable}; +use dom::bindings::guard::Guard; +use dom::bindings::utils::get_proto_or_iface_array; use js::error::throw_type_error; use js::glue::UncheckedUnwrapObject; use js::jsapi::{Class, ClassExtension, ClassSpec, GetGlobalForObjectCrossCompartment}; @@ -66,7 +67,10 @@ pub type NonNullJSNative = /// Defines constants on `obj`. /// Fails on JSAPI failure. -pub fn define_constants(cx: *mut JSContext, obj: HandleObject, constants: &'static [ConstantSpec]) { +fn define_constants( + cx: *mut JSContext, + obj: HandleObject, + constants: &[ConstantSpec]) { for spec in constants { let value = RootedValue::new(cx, spec.get_value()); unsafe { @@ -208,18 +212,20 @@ impl InterfaceConstructorBehavior { /// Create and define the interface object of a callback interface. pub unsafe fn create_callback_interface_object( cx: *mut JSContext, - receiver: HandleObject, - constants: &'static [Prefable<ConstantSpec>], - name: &'static [u8], + global: HandleObject, + constants: &[Guard<&[ConstantSpec]>], + name: &[u8], rval: MutableHandleObject) { assert!(!constants.is_empty()); rval.set(JS_NewObject(cx, ptr::null())); assert!(!rval.ptr.is_null()); - for prefable in constants { - define_constants(cx, rval.handle(), prefable.specs()); + for guard in constants { + if let Some(specs) = guard.expose(cx, rval.handle()) { + define_constants(cx, rval.handle(), specs); + } } define_name(cx, rval.handle(), name); - define_on_global_object(cx, receiver, name, rval.handle()); + define_on_global_object(cx, global, name, rval.handle()); } /// Create the interface prototype object of a non-callback interface. @@ -227,9 +233,9 @@ pub unsafe fn create_interface_prototype_object( cx: *mut JSContext, proto: HandleObject, class: &'static JSClass, - regular_methods: Option<&'static [Prefable<JSFunctionSpec>]>, - regular_properties: Option<&'static [Prefable<JSPropertySpec>]>, - constants: &'static [Prefable<ConstantSpec>], + regular_methods: &[Guard<&'static [JSFunctionSpec]>], + regular_properties: &[Guard<&'static [JSPropertySpec]>], + constants: &[Guard<&[ConstantSpec]>], rval: MutableHandleObject) { create_object(cx, proto, class, regular_methods, regular_properties, constants, rval); } @@ -237,14 +243,14 @@ pub unsafe fn create_interface_prototype_object( /// Create and define the interface object of a non-callback interface. pub unsafe fn create_noncallback_interface_object( cx: *mut JSContext, - receiver: HandleObject, + global: HandleObject, proto: HandleObject, class: &'static NonCallbackInterfaceObjectClass, - static_methods: Option<&'static [Prefable<JSFunctionSpec>]>, - static_properties: Option<&'static [Prefable<JSPropertySpec>]>, - constants: &'static [Prefable<ConstantSpec>], + static_methods: &[Guard<&'static [JSFunctionSpec]>], + static_properties: &[Guard<&'static [JSPropertySpec]>], + constants: &[Guard<&[ConstantSpec]>], interface_prototype_object: HandleObject, - name: &'static [u8], + name: &[u8], length: u32, rval: MutableHandleObject) { create_object(cx, @@ -257,14 +263,14 @@ pub unsafe fn create_noncallback_interface_object( assert!(JS_LinkConstructorAndPrototype(cx, rval.handle(), interface_prototype_object)); define_name(cx, rval.handle(), name); define_length(cx, rval.handle(), length); - define_on_global_object(cx, receiver, name, rval.handle()); + define_on_global_object(cx, global, name, rval.handle()); } /// Create and define the named constructors of a non-callback interface. pub unsafe fn create_named_constructors( cx: *mut JSContext, - receiver: HandleObject, - named_constructors: &[(NonNullJSNative, &'static [u8], u32)], + global: HandleObject, + named_constructors: &[(NonNullJSNative, &[u8], u32)], interface_prototype_object: HandleObject) { let mut constructor = RootedObject::new(cx, ptr::null_mut()); @@ -288,7 +294,7 @@ pub unsafe fn create_named_constructors( None, None)); - define_on_global_object(cx, receiver, name, constructor.handle()); + define_on_global_object(cx, global, name, constructor.handle()); } } @@ -354,42 +360,46 @@ unsafe fn create_object( cx: *mut JSContext, proto: HandleObject, class: &'static JSClass, - methods: Option<&'static [Prefable<JSFunctionSpec>]>, - properties: Option<&'static [Prefable<JSPropertySpec>]>, - constants: &'static [Prefable<ConstantSpec>], + methods: &[Guard<&'static [JSFunctionSpec]>], + properties: &[Guard<&'static [JSPropertySpec]>], + constants: &[Guard<&[ConstantSpec]>], rval: MutableHandleObject) { rval.set(JS_NewObjectWithUniqueType(cx, class, proto)); assert!(!rval.ptr.is_null()); - if let Some(methods) = methods { - define_prefable_methods(cx, rval.handle(), methods); - } - if let Some(properties) = properties { - define_prefable_properties(cx, rval.handle(), properties); - } - for prefable in constants { - define_constants(cx, rval.handle(), prefable.specs()); + define_guarded_methods(cx, rval.handle(), methods); + define_guarded_properties(cx, rval.handle(), properties); + for guard in constants { + if let Some(specs) = guard.expose(cx, rval.handle()) { + define_constants(cx, rval.handle(), specs); + } } } /// Conditionally define methods on an object. -pub unsafe fn define_prefable_methods(cx: *mut JSContext, - obj: HandleObject, - methods: &'static [Prefable<JSFunctionSpec>]) { - for prefable in methods { - define_methods(cx, obj, prefable.specs()).unwrap(); +pub unsafe fn define_guarded_methods( + cx: *mut JSContext, + obj: HandleObject, + methods: &[Guard<&'static [JSFunctionSpec]>]) { + for guard in methods { + if let Some(specs) = guard.expose(cx, obj) { + define_methods(cx, obj, specs).unwrap(); + } } } /// Conditionally define properties on an object. -pub unsafe fn define_prefable_properties(cx: *mut JSContext, - obj: HandleObject, - properties: &'static [Prefable<JSPropertySpec>]) { - for prefable in properties { - define_properties(cx, obj, prefable.specs()).unwrap(); +pub unsafe fn define_guarded_properties( + cx: *mut JSContext, + obj: HandleObject, + properties: &[Guard<&'static [JSPropertySpec]>]) { + for guard in properties { + if let Some(specs) = guard.expose(cx, obj) { + define_properties(cx, obj, specs).unwrap(); + } } } -unsafe fn define_name(cx: *mut JSContext, obj: HandleObject, name: &'static [u8]) { +unsafe fn define_name(cx: *mut JSContext, obj: HandleObject, name: &[u8]) { assert!(*name.last().unwrap() == b'\0'); let name = RootedString::new( cx, JS_AtomizeAndPinString(cx, name.as_ptr() as *const libc::c_char)); @@ -413,12 +423,12 @@ unsafe fn define_length(cx: *mut JSContext, obj: HandleObject, length: u32) { unsafe fn define_on_global_object( cx: *mut JSContext, - receiver: HandleObject, - name: &'static [u8], + global: HandleObject, + name: &[u8], obj: HandleObject) { assert!(*name.last().unwrap() == b'\0'); assert!(JS_DefineProperty1(cx, - receiver, + global, name.as_ptr() as *const libc::c_char, obj, JSPROP_RESOLVING, diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs index d69720dc538..19797a473d0 100644 --- a/components/script/dom/bindings/mod.rs +++ b/components/script/dom/bindings/mod.rs @@ -133,6 +133,7 @@ pub mod cell; pub mod conversions; pub mod error; pub mod global; +pub mod guard; pub mod inheritance; pub mod interface; pub mod js; diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 607f74456d2..0f0d5bcf00e 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -16,6 +16,7 @@ use dom::bindings::trace::trace_object; use dom::browsingcontext; use heapsize::HeapSizeOf; use js; +use js::JS_CALLEE; use js::glue::{CallJitGetterOp, CallJitMethodOp, CallJitSetterOp, IsWrapper}; use js::glue::{GetCrossCompartmentWrapper, WrapperNew}; use js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO, RUST_JSID_IS_INT, RUST_JSID_IS_STRING}; @@ -32,14 +33,12 @@ use js::jsapi::{JS_SetReservedSlot, JS_StringHasLatin1Chars, MutableHandleValue, use js::jsapi::{OnNewGlobalHookOption, RootedObject, RootedValue}; use js::jsval::{JSVal, ObjectValue, PrivateValue, UndefinedValue}; use js::rust::{GCMethods, ToString}; -use js::{JS_CALLEE}; use libc; use std::default::Default; use std::ffi::CString; use std::os::raw::c_void; use std::ptr; use std::slice; -use util::prefs; /// Proxy handler for a WindowProxy. pub struct WindowProxyHandler(pub *const libc::c_void); @@ -550,31 +549,3 @@ unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi:: pub const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks { instanceClassMatchesProto: Some(instance_class_has_proto_at_depth), }; - -/// A container around JS member specifications that are conditionally enabled. -pub struct Prefable<T: 'static> { - /// If present, the name of the preference used to conditionally enable these specs. - pub pref: Option<&'static str>, - /// The underlying slice of specifications. - pub specs: &'static [T], - /// Whether the specifications contain special terminating entries that should be - /// included or not. - pub terminator: bool, -} - -impl<T> Prefable<T> { - /// Retrieve the slice represented by this container, unless the condition - /// guarding it is false. - pub fn specs(&self) -> &'static [T] { - if let Some(pref) = self.pref { - if !prefs::get_pref(pref).as_boolean().unwrap_or(false) { - return if self.terminator { - &self.specs[self.specs.len() - 1..] - } else { - &[] - }; - } - } - self.specs - } -} |