mirror of
https://github.com/lexmount/moli.git
synced 2026-10-30 08:07:38 +00:00
feat(webidl): derive wrapping signed long long conversion
Extracted from wpt-misc-fix.
Source-commit: 4fb35a340e
This commit is contained in:
@@ -14,6 +14,7 @@ pub(crate) enum ConverterKind {
|
||||
CallbackFunction,
|
||||
CallbackInterface,
|
||||
Long,
|
||||
LongLong,
|
||||
EnforceRangeLong,
|
||||
Short,
|
||||
UnsignedShort,
|
||||
@@ -49,6 +50,7 @@ impl ConverterKind {
|
||||
"callback_function" => Ok(Self::CallbackFunction),
|
||||
"callback_interface" => Ok(Self::CallbackInterface),
|
||||
"long" => Ok(Self::Long),
|
||||
"long_long" => Ok(Self::LongLong),
|
||||
"enforce_range_long" => Ok(Self::EnforceRangeLong),
|
||||
"short" => Ok(Self::Short),
|
||||
"unsigned_short" => Ok(Self::UnsignedShort),
|
||||
@@ -81,6 +83,7 @@ impl ConverterKind {
|
||||
Self::CallbackFunction => quote!(::moli_webidl::WebIdlCallbackFunction),
|
||||
Self::CallbackInterface => quote!(::moli_webidl::WebIdlCallbackInterface),
|
||||
Self::Long => quote!(::moli_webidl::Long),
|
||||
Self::LongLong => quote!(::moli_webidl::LongLong),
|
||||
Self::EnforceRangeLong => quote!(::moli_webidl::EnforceRangeLong),
|
||||
Self::Short => quote!(::moli_webidl::Short),
|
||||
Self::UnsignedShort => quote!(::moli_webidl::UnsignedShort),
|
||||
@@ -122,6 +125,7 @@ impl ConverterKind {
|
||||
Self::BufferSource => quote!(::moli_webidl::BufferSource::from(#expr)),
|
||||
Self::CallbackFunction | Self::CallbackInterface => quote!(#expr),
|
||||
Self::Long => quote!(::moli_webidl::Long(#expr)),
|
||||
Self::LongLong => quote!(::moli_webidl::LongLong(#expr)),
|
||||
Self::EnforceRangeLong => quote!(::moli_webidl::EnforceRangeLong(#expr)),
|
||||
Self::Short => quote!(::moli_webidl::Short(#expr)),
|
||||
Self::UnsignedShort => quote!(::moli_webidl::UnsignedShort(#expr)),
|
||||
@@ -158,6 +162,7 @@ impl ConverterKind {
|
||||
Self::DomString
|
||||
| Self::UsvString
|
||||
| Self::Long
|
||||
| Self::LongLong
|
||||
| Self::EnforceRangeLong
|
||||
| Self::Short
|
||||
| Self::UnsignedShort
|
||||
@@ -372,6 +377,9 @@ fn infer_converter_kind(ty: &Type) -> Option<ConverterKind> {
|
||||
if is_type_ident(ty, "i16") {
|
||||
return Some(ConverterKind::Short);
|
||||
}
|
||||
if is_type_ident(ty, "i64") {
|
||||
return Some(ConverterKind::LongLong);
|
||||
}
|
||||
if is_type_ident(ty, "u64") {
|
||||
return Some(ConverterKind::UnsignedLongLong);
|
||||
}
|
||||
|
||||
@@ -331,6 +331,19 @@ impl<'s> WebIdlConverter<'s> for UnsignedLongLong {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> WebIdlConverter<'s> for crate::LongLong {
|
||||
type Options = ();
|
||||
fn convert(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
value: v8::Local<'s, v8::Value>,
|
||||
context: Context,
|
||||
_: &(),
|
||||
) -> Result<Self, WebIdlError> {
|
||||
number_value(scope, value, context, "long long")
|
||||
.map(|value| Self(unsigned_long_long(value) as i64))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> WebIdlConverter<'s> for EnforceRangeLongLong {
|
||||
type Options = ();
|
||||
|
||||
|
||||
@@ -95,8 +95,8 @@ pub use traits::{ParseOutcome, WebIdlArguments, WebIdlConverter, WebIdlDictionar
|
||||
pub use types::{
|
||||
Boolean, BufferSource, ByteString, ClampedUnsignedShort, Dictionary, DomString, DomString16,
|
||||
Double, EnforceRangeLong, EnforceRangeUnsignedLong, EnforceRangeUnsignedLongLong, EnumValue,
|
||||
EventListenerOptions, InterfaceObject, InterfaceOptions, Long, Record, Sequence, Short,
|
||||
StringOptions, UnrestrictedDouble, UnrestrictedFloat, UnsignedLong, UnsignedLongLong,
|
||||
EventListenerOptions, InterfaceObject, InterfaceOptions, Long, LongLong, Record, Sequence,
|
||||
Short, StringOptions, UnrestrictedDouble, UnrestrictedFloat, UnsignedLong, UnsignedLongLong,
|
||||
UnsignedShort, UsvString,
|
||||
};
|
||||
|
||||
|
||||
@@ -298,6 +298,15 @@ impl From<ClampedUnsignedShort> for u16 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub struct LongLong(pub i64);
|
||||
|
||||
impl From<LongLong> for i64 {
|
||||
fn from(value: LongLong) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub struct UnsignedLongLong(pub u64);
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
use moli_webidl::{Context, WebIdlDictionary};
|
||||
|
||||
#[derive(WebIdlDictionary)]
|
||||
#[webidl(prefix = "LongLongInit")]
|
||||
struct Init {
|
||||
#[webidl(default = 0)]
|
||||
value: i64,
|
||||
#[webidl(converter = "long_long", default = 0)]
|
||||
explicit: i64,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_long_derive_wraps_and_preserves_conversion_errors() {
|
||||
moli_v8_test_util::ensure_v8();
|
||||
let mut isolate = v8::Isolate::new(v8::CreateParams::default());
|
||||
v8::scope!(let scope, &mut isolate);
|
||||
let context = v8::Context::new(scope, Default::default());
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
for (expression, expected) in [
|
||||
("-17.9", -17),
|
||||
("NaN", 0),
|
||||
("Infinity", 0),
|
||||
("undefined", 0),
|
||||
("2**63", i64::MIN),
|
||||
("2**64", 0),
|
||||
("-(2**63)-2048", i64::MAX - 2047),
|
||||
] {
|
||||
let source = v8::String::new(
|
||||
scope,
|
||||
&format!("({{value:{expression},explicit:{expression}}})"),
|
||||
)
|
||||
.unwrap();
|
||||
let value = v8::Script::compile(scope, source, None)
|
||||
.unwrap()
|
||||
.run(scope)
|
||||
.unwrap();
|
||||
let init =
|
||||
moli_webidl::parse_dictionary::<Init>(scope, value, Context::argument("Test", 1))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(init.value, expected, "{expression}");
|
||||
assert_eq!(init.explicit, expected, "{expression}");
|
||||
}
|
||||
for source in [
|
||||
"({value:Symbol(),explicit:0})",
|
||||
"({value:0,explicit:1n})",
|
||||
"({get explicit(){throw 42},value:0})",
|
||||
] {
|
||||
v8::tc_scope!(let scope, scope);
|
||||
let source = v8::String::new(scope, source).unwrap();
|
||||
let value = v8::Script::compile(scope, source, None)
|
||||
.unwrap()
|
||||
.run(scope)
|
||||
.unwrap();
|
||||
assert!(
|
||||
moli_webidl::parse_dictionary::<Init>(scope, value, Context::argument("Test", 1))
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user