diff --git a/crates/web-sys/tests/wasm/response.rs b/crates/web-sys/tests/wasm/response.rs index 40c893f5..5da87aec 100644 --- a/crates/web-sys/tests/wasm/response.rs +++ b/crates/web-sys/tests/wasm/response.rs @@ -1,4 +1,12 @@ +extern crate futures; +extern crate js_sys; +extern crate wasm_bindgen_futures; + +use futures::Future; +use js_sys::{ArrayBuffer, DataView}; use wasm_bindgen::prelude::*; +use wasm_bindgen::JsCast; +use wasm_bindgen_futures::JsFuture; use wasm_bindgen_test::*; use web_sys::Response; @@ -8,9 +16,27 @@ extern "C" { } #[wasm_bindgen_test] -fn test_response() { +fn test_response_from_js() { let response = new_response(); assert!(!response.ok()); assert!(!response.redirected()); assert_eq!(response.status(), 501); } + +#[wasm_bindgen_test(async)] +fn test_response_from_bytes() -> impl Future { + let mut bytes: [u8; 3] = [1, 3, 5]; + let response = Response::new_with_opt_u8_array(Some(&mut bytes)).unwrap(); + assert!(response.ok()); + assert_eq!(response.status(), 200); + + let buf_promise = response.array_buffer().unwrap(); + JsFuture::from(buf_promise).map(move |buf_val| { + assert!(buf_val.is_instance_of::()); + let array_buf: ArrayBuffer = buf_val.dyn_into().unwrap(); + let data_view = DataView::new(&array_buf, 0, bytes.len()); + for (i, byte) in bytes.iter().enumerate() { + assert_eq!(&data_view.get_uint8(i), byte); + } + }) +} diff --git a/crates/webidl/src/idl_type.rs b/crates/webidl/src/idl_type.rs index 8d20eb13..6d3847d3 100644 --- a/crates/webidl/src/idl_type.rs +++ b/crates/webidl/src/idl_type.rs @@ -63,24 +63,26 @@ pub(crate) enum IdlType<'a> { Any, Void, + + UnknownInterface(&'a str), } pub(crate) trait ToIdlType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option>; + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a>; } impl<'a> ToIdlType<'a> for UnionType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { let mut idl_types = Vec::with_capacity(self.body.list.len()); for t in &self.body.list { - idl_types.push(t.to_idl_type(record)?); + idl_types.push(t.to_idl_type(record)); } - Some(IdlType::Union(idl_types)) + IdlType::Union(idl_types) } } impl<'a> ToIdlType<'a> for Type<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { match self { Type::Single(t) => t.to_idl_type(record), Type::Union(t) => t.to_idl_type(record), @@ -89,7 +91,7 @@ impl<'a> ToIdlType<'a> for Type<'a> { } impl<'a> ToIdlType<'a> for SingleType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { match self { SingleType::Any(t) => t.to_idl_type(record), SingleType::NonAny(t) => t.to_idl_type(record), @@ -98,7 +100,7 @@ impl<'a> ToIdlType<'a> for SingleType<'a> { } impl<'a> ToIdlType<'a> for NonAnyType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { match self { NonAnyType::Promise(t) => t.to_idl_type(record), NonAnyType::Integer(t) => t.to_idl_type(record), @@ -134,42 +136,36 @@ impl<'a> ToIdlType<'a> for NonAnyType<'a> { } impl<'a> ToIdlType<'a> for SequenceType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { - Some(IdlType::Sequence(Box::new( - self.generics.body.to_idl_type(record)?, - ))) + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { + IdlType::Sequence(Box::new(self.generics.body.to_idl_type(record))) } } impl<'a> ToIdlType<'a> for FrozenArrayType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { - Some(IdlType::FrozenArray(Box::new( - self.generics.body.to_idl_type(record)?, - ))) + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { + IdlType::FrozenArray(Box::new(self.generics.body.to_idl_type(record))) } } impl<'a, T: ToIdlType<'a>> ToIdlType<'a> for MayBeNull { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { - let inner_idl_type = self.type_.to_idl_type(record)?; + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { + let inner_idl_type = self.type_.to_idl_type(record); if self.q_mark.is_some() { - Some(IdlType::Nullable(Box::new(inner_idl_type))) + IdlType::Nullable(Box::new(inner_idl_type)) } else { - Some(inner_idl_type) + inner_idl_type } } } impl<'a> ToIdlType<'a> for PromiseType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { - Some(IdlType::Promise(Box::new( - self.generics.body.to_idl_type(record)?, - ))) + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { + IdlType::Promise(Box::new(self.generics.body.to_idl_type(record))) } } impl<'a> ToIdlType<'a> for IntegerType { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { match self { IntegerType::LongLong(t) => t.to_idl_type(record), IntegerType::Long(t) => t.to_idl_type(record), @@ -179,37 +175,37 @@ impl<'a> ToIdlType<'a> for IntegerType { } impl<'a> ToIdlType<'a> for LongLongType { - fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> IdlType<'a> { if self.unsigned.is_some() { - Some(IdlType::UnsignedLongLong) + IdlType::UnsignedLongLong } else { - Some(IdlType::LongLong) + IdlType::LongLong } } } impl<'a> ToIdlType<'a> for LongType { - fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> IdlType<'a> { if self.unsigned.is_some() { - Some(IdlType::UnsignedLong) + IdlType::UnsignedLong } else { - Some(IdlType::Long) + IdlType::Long } } } impl<'a> ToIdlType<'a> for ShortType { - fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> IdlType<'a> { if self.unsigned.is_some() { - Some(IdlType::UnsignedShort) + IdlType::UnsignedShort } else { - Some(IdlType::Short) + IdlType::Short } } } impl<'a> ToIdlType<'a> for FloatingPointType { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { match self { FloatingPointType::Float(t) => t.to_idl_type(record), FloatingPointType::Double(t) => t.to_idl_type(record), @@ -218,36 +214,36 @@ impl<'a> ToIdlType<'a> for FloatingPointType { } impl<'a> ToIdlType<'a> for FloatType { - fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> IdlType<'a> { if self.unrestricted.is_some() { - Some(IdlType::UnrestrictedFloat) + IdlType::UnrestrictedFloat } else { - Some(IdlType::Float) + IdlType::Float } } } impl<'a> ToIdlType<'a> for DoubleType { - fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> IdlType<'a> { if self.unrestricted.is_some() { - Some(IdlType::UnrestrictedDouble) + IdlType::UnrestrictedDouble } else { - Some(IdlType::Double) + IdlType::Double } } } impl<'a> ToIdlType<'a> for RecordType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { - Some(IdlType::Record( - Box::new(self.generics.body.0.to_idl_type(record)?), - Box::new(self.generics.body.2.to_idl_type(record)?), - )) + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { + IdlType::Record( + Box::new(self.generics.body.0.to_idl_type(record)), + Box::new(self.generics.body.2.to_idl_type(record)), + ) } } impl<'a> ToIdlType<'a> for StringType { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { match self { StringType::Byte(t) => t.to_idl_type(record), StringType::DOM(t) => t.to_idl_type(record), @@ -257,7 +253,7 @@ impl<'a> ToIdlType<'a> for StringType { } impl<'a> ToIdlType<'a> for UnionMemberType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { match self { UnionMemberType::Single(t) => t.to_idl_type(record), UnionMemberType::Union(t) => t.to_idl_type(record), @@ -266,7 +262,7 @@ impl<'a> ToIdlType<'a> for UnionMemberType<'a> { } impl<'a> ToIdlType<'a> for ConstType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { match self { ConstType::Integer(t) => t.to_idl_type(record), ConstType::FloatingPoint(t) => t.to_idl_type(record), @@ -279,7 +275,7 @@ impl<'a> ToIdlType<'a> for ConstType<'a> { } impl<'a> ToIdlType<'a> for ReturnType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { match self { ReturnType::Void(t) => t.to_idl_type(record), ReturnType::Type(t) => t.to_idl_type(record), @@ -288,31 +284,31 @@ impl<'a> ToIdlType<'a> for ReturnType<'a> { } impl<'a> ToIdlType<'a> for AttributedType<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { self.type_.to_idl_type(record) } } impl<'a> ToIdlType<'a> for Identifier<'a> { - fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option> { + fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> IdlType<'a> { if self.0 == "DOMTimeStamp" { // https://heycam.github.io/webidl/#DOMTimeStamp - Some(IdlType::UnsignedLongLong) + IdlType::UnsignedLongLong } else if let Some(idl_type) = record.typedefs.get(&self.0) { idl_type.to_idl_type(record) } else if record.interfaces.contains_key(self.0) { - Some(IdlType::Interface(self.0)) + IdlType::Interface(self.0) } else if record.dictionaries.contains_key(self.0) { - Some(IdlType::Dictionary(self.0)) + IdlType::Dictionary(self.0) } else if record.enums.contains_key(self.0) { - Some(IdlType::Enum(self.0)) + IdlType::Enum(self.0) } else if record.callbacks.contains(self.0) { - Some(IdlType::Callback) + IdlType::Callback } else if let Some(data) = record.callback_interfaces.get(self.0) { - Some(IdlType::CallbackInterface { + IdlType::CallbackInterface { name: self.0, single_function: data.single_function, - }) + } } else if self.0 == "WindowProxy" { // See this for more info: // @@ -320,10 +316,10 @@ impl<'a> ToIdlType<'a> for Identifier<'a> { // // namely this seems to be "legalese" for "this is a `Window`", so // let's translate it as such. - Some(IdlType::Interface("Window")) + IdlType::Interface("Window") } else { warn!("Unrecognized type: {}", self.0); - None + IdlType::UnknownInterface(self.0) } } } @@ -331,8 +327,8 @@ impl<'a> ToIdlType<'a> for Identifier<'a> { macro_rules! terms_to_idl_type { ($($t:tt => $r:tt)*) => ($( impl<'a> ToIdlType<'a> for term::$t { - fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> Option> { - Some(IdlType::$r) + fn to_idl_type(&self, _record: &FirstPassRecord<'a>) -> IdlType<'a> { + IdlType::$r } } )*) @@ -406,6 +402,7 @@ impl<'a> IdlType<'a> { IdlType::BufferSource => dst.push_str("buffer_source"), IdlType::Interface(name) => dst.push_str(&snake_case_ident(name)), + IdlType::UnknownInterface(name) => dst.push_str(&snake_case_ident(name)), IdlType::Dictionary(name) => dst.push_str(&snake_case_ident(name)), IdlType::Enum(name) => dst.push_str(&snake_case_ident(name)), IdlType::CallbackInterface { name, .. } => dst.push_str(&snake_case_ident(name)), @@ -587,6 +584,7 @@ impl<'a> IdlType<'a> { } IdlType::Void => None, IdlType::Callback => js_sys("Function"), + IdlType::UnknownInterface(_) => None, } } diff --git a/crates/webidl/src/lib.rs b/crates/webidl/src/lib.rs index 3c7720f9..0c1bd020 100644 --- a/crates/webidl/src/lib.rs +++ b/crates/webidl/src/lib.rs @@ -353,7 +353,7 @@ impl<'src> FirstPassRecord<'src> { // use argument position now as we're just binding setters let ty = field .type_ - .to_idl_type(self)? + .to_idl_type(self) .to_syn_type(TypePosition::Argument)?; // Slice types aren't supported because they don't implement @@ -459,11 +459,7 @@ impl<'src> FirstPassRecord<'src> { self_name: &'src str, member: &'src weedle::interface::ConstMember<'src>, ) { - let idl_type = match member.const_type.to_idl_type(self) { - Some(idl_type) => idl_type, - None => return, - }; - + let idl_type = member.const_type.to_idl_type(self); let ty = match idl_type.to_syn_type(TypePosition::Return) { Some(ty) => ty, None => { diff --git a/crates/webidl/src/util.rs b/crates/webidl/src/util.rs index 0cbf684e..2acee7d6 100644 --- a/crates/webidl/src/util.rs +++ b/crates/webidl/src/util.rs @@ -336,7 +336,7 @@ impl<'src> FirstPassRecord<'src> { ) -> Option { let kind = backend::ast::OperationKind::Getter(Some(raw_ident(name))); let kind = self.import_function_kind(self_name, is_static, kind); - let ret = ty.to_idl_type(self)?; + let ret = ty.to_idl_type(self); self.create_one_function( &name, &snake_case_ident(name), @@ -366,7 +366,7 @@ impl<'src> FirstPassRecord<'src> { ) -> Option { let kind = backend::ast::OperationKind::Setter(Some(raw_ident(name))); let kind = self.import_function_kind(self_name, is_static, kind); - let field_ty = field_ty.to_idl_type(self)?; + let field_ty = field_ty.to_idl_type(self); self.create_one_function( &name, &format!("set_{}", name).to_snake_case(), @@ -431,10 +431,7 @@ impl<'src> FirstPassRecord<'src> { ); signatures.push((signature, idl_args.clone())); } - match arg.ty.to_idl_type(self) { - Some(t) => idl_args.push(t), - None => continue 'outer, - } + idl_args.push(arg.ty.to_idl_type(self)); } signatures.push((signature, idl_args)); } @@ -517,10 +514,7 @@ impl<'src> FirstPassRecord<'src> { // TODO: overloads probably never change return types, so we should // do this much earlier to avoid all the above work if // possible. - let ret_ty = match signature.orig.ret.to_idl_type(self) { - Some(ty) => ty, - None => continue, - }; + let ret_ty = signature.orig.ret.to_idl_type(self); let mut rust_name = snake_case_ident(name); let mut first = true;