Auto merge of #26170 - Manishearth:enum-convertible, r=asajeffrey

Add FromJSValConvertible for enums

Fixes https://github.com/servo/servo/issues/26169

This adds FromJSValConvertible implementations for webidl enums, which allows them to be used within `sequence<>`, etc.

This also uses these implementations when converting arguments.
This commit is contained in:
bors-servo 2020-04-12 11:47:43 -04:00 committed by GitHub
commit 3abbfdf278
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1004,17 +1004,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
"yet")
enum = type.inner.identifier.name
if invalidEnumValueFatal:
handleInvalidEnumValueCode = onFailureInvalidEnumValue(failureCode, 'search').define()
handleInvalidEnumValueCode = failureCode or "throw_type_error(*cx, &error); %s" % exceptionCode
else:
handleInvalidEnumValueCode = "return true;"
template = (
"match find_enum_value(*cx, ${val}, %(pairs)s) {\n"
"match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {"
" Err(_) => { %(exceptionCode)s },\n"
" Ok((None, search)) => { %(handleInvalidEnumValueCode)s },\n"
" Ok((Some(&value), _)) => value,\n"
"}" % {"pairs": enum + "Values::pairs",
"exceptionCode": exceptionCode,
" Ok(ConversionResult::Success(v)) => v,\n"
" Ok(ConversionResult::Failure(error)) => { %(handleInvalidEnumValueCode)s },\n"
"}" % {"exceptionCode": exceptionCode,
"handleInvalidEnumValueCode": handleInvalidEnumValueCode})
if defaultValue is not None:
@ -2418,7 +2417,6 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
'crate::dom::bindings::str::DOMString',
'crate::dom::bindings::str::USVString',
'crate::dom::bindings::trace::RootedTraceableBox',
'crate::dom::bindings::utils::find_enum_value',
'crate::dom::types::*',
'crate::dom::windowproxy::WindowProxy',
'crate::script_runtime::JSContext as SafeJSContext',
@ -4347,8 +4345,12 @@ pub enum %s {
pairs = ",\n ".join(['("%s", super::%s::%s)' % (val, ident, getEnumValueName(val)) for val in enum.values()])
inner = string.Template("""\
use crate::dom::bindings::conversions::ConversionResult;
use crate::dom::bindings::conversions::FromJSValConvertible;
use crate::dom::bindings::conversions::ToJSValConvertible;
use crate::dom::bindings::utils::find_enum_value;
use js::jsapi::JSContext;
use js::rust::HandleValue;
use js::rust::MutableHandleValue;
use js::jsval::JSVal;
@ -4373,6 +4375,22 @@ impl ToJSValConvertible for super::${ident} {
pairs[*self as usize].0.to_jsval(cx, rval);
}
}
impl FromJSValConvertible for super::${ident} {
type Config = ();
unsafe fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ())
-> Result<ConversionResult<super::${ident}>, ()> {
match find_enum_value(cx, value, pairs) {
Err(_) => Err(()),
Ok((None, search)) => {
Ok(ConversionResult::Failure(
format!("'{}' is not a valid enum value for enumeration '${ident}'.", search).into()
))
}
Ok((Some(&value), _)) => Ok(ConversionResult::Success(value)),
}
}
}
""").substitute({
'ident': ident,
'pairs': pairs
@ -6138,7 +6156,6 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'crate::dom::bindings::utils::ProtoOrIfaceArray',
'crate::dom::bindings::utils::enumerate_global',
'crate::dom::bindings::utils::finalize_global',
'crate::dom::bindings::utils::find_enum_value',
'crate::dom::bindings::utils::generic_getter',
'crate::dom::bindings::utils::generic_lenient_getter',
'crate::dom::bindings::utils::generic_lenient_setter',