diff --git a/examples/todomvc/static/css/todomvc-app-css/index.css b/examples/todomvc/static/css/todomvc-app-css/index.css
index e6e089cb..e8cc03a3 100644
--- a/examples/todomvc/static/css/todomvc-app-css/index.css
+++ b/examples/todomvc/static/css/todomvc-app-css/index.css
@@ -189,11 +189,11 @@ label[for='toggle-all'] {
}
.todo-list li .toggle:after {
- content: url('data:image/svg+xml;utf8,');
+ content: url('data:image/svg+xml;utf8,');
}
.todo-list li .toggle:checked:after {
- content: url('data:image/svg+xml;utf8,');
+ content: url('data:image/svg+xml;utf8,');
}
.todo-list li label {
diff --git a/src/ecosystem/serde.rs b/src/ecosystem/serde.rs
index b8fef8eb..3f09f839 100644
--- a/src/ecosystem/serde.rs
+++ b/src/ecosystem/serde.rs
@@ -168,15 +168,15 @@ impl Serialize for Value {
} else if Object::instance_of( reference ) {
let object: Object = reference.try_into().unwrap();
let value: BTreeMap< String, Value > = object.into();
- let mut map = try!( serializer.serialize_map( Some( value.len() ) ) );
+ let mut map = serializer.serialize_map( Some( value.len() ) )?;
for (key, value) in value {
- try!( map.serialize_key( &key ) );
- try!( map.serialize_value( &value ) );
+ map.serialize_key( &key )?;
+ map.serialize_value( &value )?;
}
map.end()
} else {
- let map = try!( serializer.serialize_map( None ) );
+ let map = serializer.serialize_map( None )?;
map.end()
}
}
@@ -377,7 +377,7 @@ impl From< ConversionError > for value::ConversionError {
}
}
-#[derive(Debug)]
+#[derive(Default, Debug)]
pub struct Serializer {
}
@@ -526,7 +526,7 @@ impl< 'a > ser::Serializer for &'a mut Serializer {
}
#[doc(hidden)]
-#[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))]
+#[allow(clippy::needless_pass_by_value)]
#[inline]
pub fn to_value< T: Serialize >( value: T ) -> Result< Value, ConversionError > {
let mut serializer = Serializer {};
@@ -869,8 +869,8 @@ impl< 'de > de::Deserializer< 'de > for Value {
};
visitor.visit_enum( EnumDeserializer {
- variant: variant,
- value: value,
+ variant,
+ value,
})
}
@@ -1254,7 +1254,7 @@ impl< T: fmt::Debug > fmt::Debug for Serde< T > {
impl< T: Serialize > JsSerialize for Serde< T > {
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( &self ) -> SerializedValue {
let value = to_value( &self.0 ).unwrap();
global_arena::serialize_value( value )
}
diff --git a/src/ecosystem/serde_json.rs b/src/ecosystem/serde_json.rs
index ca713dee..b2311b25 100644
--- a/src/ecosystem/serde_json.rs
+++ b/src/ecosystem/serde_json.rs
@@ -35,7 +35,7 @@ impl TryFrom< JsonValue > for Value {
JsonValue::Object( value ) => {
let mut map: BTreeMap< String, Value > = BTreeMap::new();
for (key, value) in value.into_iter() {
- map.insert( key.into(), value.try_into()? );
+ map.insert( key, value.try_into()? );
}
map.into()
diff --git a/src/lib.rs b/src/lib.rs
index fde84f75..a918fc3d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -539,6 +539,17 @@ pub mod traits {
pub use super::web::midi::IMidiPort;
}
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn bla() {
+ // use webcore::try_from::TryInto;
+ // let res:bool = js!{ false }.try_into().unwrap();
+ // assert!(res);
+ println!("hi");
+ }
+}
+
#[doc(hidden)]
pub mod private {
#[cfg(all(target_arch = "wasm32", target_vendor = "unknown", target_os = "unknown", not(cargo_web)))]
@@ -551,7 +562,7 @@ pub mod private {
pub use webcore::serialization::{
JsSerialize,
JsSerializeOwned,
- SerializedValue
+ SerializedValue,
};
pub use webcore::newtype::{
diff --git a/src/webapi/array_buffer.rs b/src/webapi/array_buffer.rs
index 0da70f0d..b234d0ff 100644
--- a/src/webapi/array_buffer.rs
+++ b/src/webapi/array_buffer.rs
@@ -26,8 +26,12 @@ impl ArrayBuffer {
// https://www.ecma-international.org/ecma-262/6.0/#sec-get-arraybuffer.prototype.bytelength
pub fn len( &self ) -> u64 {
let reference = self.as_ref();
- let length = js!( return @{reference}.byteLength; ).try_into().unwrap();
- length
+ js!( return @{reference}.byteLength; ).try_into().unwrap()
+ }
+
+ /// Returns `true` if the buffer contains no bytes.
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
}
}
diff --git a/src/webapi/blob.rs b/src/webapi/blob.rs
index 09db2728..0bf00a64 100644
--- a/src/webapi/blob.rs
+++ b/src/webapi/blob.rs
@@ -77,6 +77,11 @@ pub trait IBlob: ReferenceType {
{
slice_blob(self, range, Some(content_type))
}
+
+ /// Returns `true` if the `Blob` contains no bytes.
+ fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
/// A reference to a JavaScript object which implements the [IBlob](trait.IBlob.html)
@@ -90,6 +95,12 @@ pub struct Blob( Reference );
impl IBlob for Blob {}
+impl Default for Blob {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
impl Blob {
/// Creates a new `Blob`.
///
diff --git a/src/webapi/date.rs b/src/webapi/date.rs
index 49476625..349e30bc 100644
--- a/src/webapi/date.rs
+++ b/src/webapi/date.rs
@@ -13,6 +13,7 @@ impl Date {
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
// https://www.ecma-international.org/ecma-262/6.0/#sec-date-constructor-date
+ #[allow(clippy::new_without_default)] // Because this generates a different value every time, Default is not appropriate.
pub fn new() -> Self {
js!(
return new Date();
@@ -485,6 +486,7 @@ impl Date {
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toString)
// https://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype.tostring
#[inline]
+ #[allow(clippy::inherent_to_string)] // We're matching the JS api here.
pub fn to_string(&self) -> String {
js!(
return @{self}.toString();
diff --git a/src/webapi/document.rs b/src/webapi/document.rs
index e01c8ccf..05875209 100644
--- a/src/webapi/document.rs
+++ b/src/webapi/document.rs
@@ -1,6 +1,8 @@
use webcore::value::{Reference, Value};
use webcore::try_from::{TryInto, TryFrom};
+#[cfg(feature = "experimental_features_which_may_break_on_minor_version_bumps")]
use webcore::promise::{Promise, TypedPromise};
+#[cfg(feature = "experimental_features_which_may_break_on_minor_version_bumps")]
use webapi::error::TypeError;
use webapi::event_target::{IEventTarget, EventTarget};
use webapi::node::{INode, Node, CloneKind};
diff --git a/src/webapi/element.rs b/src/webapi/element.rs
index 3e045150..df1110b3 100644
--- a/src/webapi/element.rs
+++ b/src/webapi/element.rs
@@ -1,6 +1,8 @@
use webcore::value::Reference;
use webcore::try_from::{TryFrom, TryInto};
+#[cfg(feature = "experimental_features_which_may_break_on_minor_version_bumps")]
use webcore::promise::{Promise, TypedPromise};
+#[cfg(feature = "experimental_features_which_may_break_on_minor_version_bumps")]
use webapi::error::TypeError;
use webapi::dom_exception::{InvalidCharacterError, InvalidPointerId, NoModificationAllowedError, SyntaxError};
use webapi::event_target::{IEventTarget, EventTarget};
@@ -315,8 +317,8 @@ pub enum InsertPosition {
AfterEnd,
}
-/// Errors thrown by `Element::insert_adjacent_html`.
error_enum_boilerplate! {
+ /// Errors thrown by `Element::insert_adjacent_html`.
InsertAdjacentError,
NoModificationAllowedError, SyntaxError
}
diff --git a/src/webapi/event_target.rs b/src/webapi/event_target.rs
index 25e84d6c..7a12bca1 100644
--- a/src/webapi/event_target.rs
+++ b/src/webapi/event_target.rs
@@ -60,7 +60,7 @@ pub trait IEventTarget: ReferenceType {
EventListenerHandle {
event_type: T::EVENT_TYPE,
reference: reference.clone(),
- listener_reference: listener_reference
+ listener_reference
}
}
diff --git a/src/webapi/events/drag.rs b/src/webapi/events/drag.rs
index 1b3c7d0e..e2628254 100644
--- a/src/webapi/events/drag.rs
+++ b/src/webapi/events/drag.rs
@@ -486,6 +486,11 @@ impl DataTransferItemList {
index: 0,
}
}
+
+ /// Returns `true` if there are no drag items in the list.
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
impl IntoIterator for DataTransferItemList {
@@ -598,10 +603,8 @@ impl DataTransferItem {
pub fn get_as_string_future( &self ) -> oneshot::Receiver {
let (sender, receiver) = oneshot::channel();
let callback = |s: String| {
- match sender.send(s) {
- Ok(_) => {},
- Err(_) => {},
- };
+ // Ignore the Result, Ok gives () and Err only happens if the receiver is dropped before this is called, which is fine.
+ let _ = sender.send(s);
};
js!(@(no_return)
diff --git a/src/webapi/events/mouse.rs b/src/webapi/events/mouse.rs
index 46261b0f..f6dca3dc 100644
--- a/src/webapi/events/mouse.rs
+++ b/src/webapi/events/mouse.rs
@@ -227,7 +227,7 @@ pub struct MouseButtonsState(u8);
impl MouseButtonsState {
/// Check if a [MouseButton](enum.MouseButton.html) is currently pressed
- pub fn is_down(&self, button: MouseButton) -> bool {
+ pub fn is_down(self, button: MouseButton) -> bool {
match button {
MouseButton::Left => self.0 & 0b1 != 0,
MouseButton::Right => self.0 & 0b10 != 0,
diff --git a/src/webapi/file_list.rs b/src/webapi/file_list.rs
index 57b51185..eb9aea2c 100644
--- a/src/webapi/file_list.rs
+++ b/src/webapi/file_list.rs
@@ -29,6 +29,11 @@ impl FileList {
index: 0
}
}
+
+ /// Returns `true` if the list contains no Files
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
impl IntoIterator for FileList {
diff --git a/src/webapi/file_reader.rs b/src/webapi/file_reader.rs
index 2ee408fe..5fc18a23 100644
--- a/src/webapi/file_reader.rs
+++ b/src/webapi/file_reader.rs
@@ -41,6 +41,12 @@ pub enum FileReaderReadyState {
Done
}
+impl Default for FileReader {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
impl FileReader {
/// Returns a newly constructed `FileReader`.
///
diff --git a/src/webapi/form_data.rs b/src/webapi/form_data.rs
index ebede27f..2bfdb201 100644
--- a/src/webapi/form_data.rs
+++ b/src/webapi/form_data.rs
@@ -63,6 +63,12 @@ impl TryFrom< Value > for Option< FormDataEntry > {
}
}
+impl Default for FormData {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
impl FormData {
/// Creates a new `FormData`.
///
diff --git a/src/webapi/global.rs b/src/webapi/global.rs
index 4c039ac7..6e511cca 100644
--- a/src/webapi/global.rs
+++ b/src/webapi/global.rs
@@ -13,5 +13,5 @@ pub fn alert( message: &str ) {
/// An alias for [window.confirm](struct.Window.html#method.confirm).
pub fn confirm( message: &str ) -> bool {
- return window().confirm( message );
+ window().confirm( message )
}
diff --git a/src/webapi/history.rs b/src/webapi/history.rs
index c99a9eec..c0de69f3 100644
--- a/src/webapi/history.rs
+++ b/src/webapi/history.rs
@@ -96,4 +96,9 @@ impl History {
return @{self}.length;
).try_into().unwrap()
}
+
+ /// Returns `true` if there are no history entries.
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
diff --git a/src/webapi/html_collection.rs b/src/webapi/html_collection.rs
index 337265dc..3f6c253c 100644
--- a/src/webapi/html_collection.rs
+++ b/src/webapi/html_collection.rs
@@ -41,6 +41,11 @@ impl HtmlCollection {
index: 0
}
}
+
+ /// Returns true if the collection contains no elements
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
diff --git a/src/webapi/html_elements/image.rs b/src/webapi/html_elements/image.rs
index 13a4f9b6..d543b8d5 100644
--- a/src/webapi/html_elements/image.rs
+++ b/src/webapi/html_elements/image.rs
@@ -21,6 +21,12 @@ impl INode for ImageElement {}
impl IElement for ImageElement {}
impl IHtmlElement for ImageElement {}
+impl Default for ImageElement {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
impl ImageElement {
/// Constructs a new ImageElement.
///
diff --git a/src/webapi/html_elements/slot.rs b/src/webapi/html_elements/slot.rs
index a269189f..a0ebb480 100644
--- a/src/webapi/html_elements/slot.rs
+++ b/src/webapi/html_elements/slot.rs
@@ -18,8 +18,8 @@ pub enum SlotContentKind {
}
impl SlotContentKind {
- fn to_bool(&self) -> bool {
- match *self {
+ fn to_bool(self) -> bool {
+ match self {
SlotContentKind::AssignedOnly => false,
SlotContentKind::WithFallback => true,
}
diff --git a/src/webapi/midi.rs b/src/webapi/midi.rs
index 3b374740..de558146 100644
--- a/src/webapi/midi.rs
+++ b/src/webapi/midi.rs
@@ -86,7 +86,7 @@ impl MidiAccess {
/// The MIDI input ports available to the system.
// https://webaudio.github.io/web-midi-api/#dom-midiaccess-inputs
pub fn inputs( &self ) -> MidiInputMap {
- return js!(
+ js!(
return @{self}.inputs;
).try_into().unwrap()
}
@@ -94,7 +94,7 @@ impl MidiAccess {
/// The MIDI output ports available to the system.
// https://webaudio.github.io/web-midi-api/#dom-midiaccess-outputs
pub fn outputs( &self ) -> MidiOutputMap {
- return js!(
+ js!(
return @{self}.outputs;
).try_into().unwrap()
}
@@ -102,7 +102,7 @@ impl MidiAccess {
/// This attribute informs the user whether system exclusive support is enabled.
// https://webaudio.github.io/web-midi-api/#dom-midiaccess-sysexenabled
pub fn sysex_enabled( &self ) -> bool {
- return js!(
+ js!(
return @{self}.sysexEnabled;
).try_into().unwrap()
}
@@ -189,13 +189,13 @@ pub trait IMidiPort: IEventTarget {
/// has chosen for their application.
// https://webaudio.github.io/web-midi-api/#dom-midiport-id
fn id( &self ) -> String {
- return js!( return @{self.as_ref()}.id; ).try_into().unwrap();
+ js!( return @{self.as_ref()}.id; ).try_into().unwrap()
}
/// The system name of the port.
// https://webaudio.github.io/web-midi-api/#dom-midiport-name
fn name( &self ) -> Option< String > {
- return js!( return @{self.as_ref()}.name; ).try_into().unwrap();
+ js!( return @{self.as_ref()}.name; ).try_into().unwrap()
}
}
diff --git a/src/webapi/mutation_observer.rs b/src/webapi/mutation_observer.rs
index 649b5420..fd0374bf 100644
--- a/src/webapi/mutation_observer.rs
+++ b/src/webapi/mutation_observer.rs
@@ -63,6 +63,7 @@ impl MutationObserver {
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#Constructor)
// https://dom.spec.whatwg.org/#ref-for-dom-mutationobserver-mutationobserver
+ #[allow(clippy::new_ret_no_self)]
pub fn new< F >( callback: F ) -> MutationObserverHandle
where F: FnMut( Vec< MutationRecord >, Self ) + 'static {
let callback_reference: Reference = js! ( return @{Mut(callback)}; ).try_into().unwrap();
@@ -252,19 +253,19 @@ impl TryFrom< Value > for MutationRecord {
match kind.as_str() {
"attributes" => Ok( MutationRecord::Attribute {
- target: target,
+ target,
name: js!( return @{r}.attributeName; ).try_into()?,
namespace: js!( return @{r}.attributeNamespace; ).try_into()?,
old_value: js!( return @{r}.oldValue; ).try_into()?,
} ),
"characterData" => Ok( MutationRecord::CharacterData {
- target: target,
+ target,
old_data: js!( return @{r}.oldValue; ).try_into()?,
} ),
"childList" => Ok( MutationRecord::ChildList {
- target: target,
+ target,
inserted_nodes: js!( return @{r}.addedNodes; ).try_into()?,
removed_nodes: js!( return @{r}.removedNodes; ).try_into()?,
previous_sibling: js!( return @{r}.previousSibling; ).try_into()?,
diff --git a/src/webapi/node.rs b/src/webapi/node.rs
index 1c735b08..12409f46 100644
--- a/src/webapi/node.rs
+++ b/src/webapi/node.rs
@@ -1,5 +1,3 @@
-use std::mem;
-
use webcore::value::Reference;
use webcore::try_from::{TryFrom, TryInto};
use webapi::document::Document;
@@ -30,7 +28,8 @@ pub trait INode: IEventTarget {
fn as_node( &self ) -> &Node {
let reference: &Reference = self.as_ref();
unsafe {
- mem::transmute( reference )
+ //TODO: Is this really always safe? Can't downstream implementors implement INode?
+ &*(reference as *const Reference as *const Node)
}
}
@@ -344,8 +343,9 @@ pub trait INode: IEventTarget {
}
}
-/// Errors thrown by `Node` insertion methods.
+
error_enum_boilerplate! {
+ /// Errors thrown by `Node` insertion methods.
InsertNodeError,
NotFoundError, HierarchyRequestError
}
diff --git a/src/webapi/node_list.rs b/src/webapi/node_list.rs
index 04cfb3c8..a2e35cb9 100644
--- a/src/webapi/node_list.rs
+++ b/src/webapi/node_list.rs
@@ -47,6 +47,11 @@ impl NodeList {
index: 0
}
}
+
+ /// Returns `true` if the list contains no Nodes.
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
impl IntoIterator for NodeList {
diff --git a/src/webapi/rendering_context.rs b/src/webapi/rendering_context.rs
index 4ac8d33f..ffdedaa3 100644
--- a/src/webapi/rendering_context.rs
+++ b/src/webapi/rendering_context.rs
@@ -1059,6 +1059,7 @@ impl CanvasRenderingContext2d {
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage)
// https://html.spec.whatwg.org/#2dcontext:dom-context-2d-drawimage
+ #[allow(clippy::too_many_arguments)] // I would agree it's too many, but we're trying to match the standard.
pub fn draw_image_s(&self, image: ImageElement,
sx: f64, sy: f64, s_width: f64, s_height: f64,
dx: f64, dy: f64, d_width: f64, d_height: f64
@@ -1210,6 +1211,7 @@ impl CanvasRenderingContext2d {
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData)
// https://html.spec.whatwg.org/#2dcontext:dom-context-2d-putimagedata
+ #[allow(clippy::too_many_arguments)] // I would agree it's too many, but we're trying to match the standard.
pub fn put_image_data_dirty(&self,
image_data: ImageData,
dx: f32, dy: f32,
@@ -1306,6 +1308,7 @@ impl CanvasRenderingContext2d {
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform)
// https://html.spec.whatwg.org/#2dcontext:dom-context-2d-settransform
+ #[allow(clippy::many_single_char_names)]
pub fn set_transform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
js! { @(no_return)
@{&self.0}.setTransform(@{a}, @{b}, @{c}, @{d}, @{e}, @{f});
@@ -1359,6 +1362,7 @@ impl CanvasRenderingContext2d {
///
/// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/transform)
// https://html.spec.whatwg.org/#2dcontext:dom-context-2d-transform
+ #[allow(clippy::many_single_char_names)]
pub fn transform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
js! { @(no_return)
@{&self.0}.transform(@{a}, @{b}, @{c}, @{d}, @{e}, @{f});
diff --git a/src/webapi/shadow_root.rs b/src/webapi/shadow_root.rs
index afb42d3c..ed6ec868 100644
--- a/src/webapi/shadow_root.rs
+++ b/src/webapi/shadow_root.rs
@@ -19,8 +19,8 @@ pub enum ShadowRootMode {
}
impl ShadowRootMode {
- pub(crate) fn as_str(&self) -> &'static str {
- match *self {
+ pub(crate) fn as_str(self) -> &'static str {
+ match self {
ShadowRootMode::Open => "open",
ShadowRootMode::Closed => "closed",
}
diff --git a/src/webapi/storage.rs b/src/webapi/storage.rs
index c1aa748e..1585ff50 100644
--- a/src/webapi/storage.rs
+++ b/src/webapi/storage.rs
@@ -68,8 +68,13 @@ impl Storage {
js!( return @{self}.key( @{nth} ); ).try_into().ok()
}
- /// Returns true if the storage contains a value for the specified key.
+ /// Returns `true` if the storage contains a value for the specified key.
pub fn contains_key( &self, key: &str ) -> bool {
js!( return !!@{self}.getItem( @{key} ); ).try_into().unwrap()
}
+
+ /// Returns `true` if the storage contains no data items.
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
diff --git a/src/webapi/timer_future.rs b/src/webapi/timer_future.rs
index d1441c26..8e1d84fb 100644
--- a/src/webapi/timer_future.rs
+++ b/src/webapi/timer_future.rs
@@ -36,11 +36,8 @@ impl Wait {
let ( sender, receiver ) = oneshot::channel();
let callback = move || {
- // TODO is this correct ?
- match sender.send( () ) {
- Ok( _ ) => {},
- Err( _ ) => {},
- };
+ // We unwrap here because an Error value indicates a significant bug in this code.
+ sender.send(()).unwrap();
};
let timer = js!(
@@ -66,7 +63,7 @@ impl Future for Wait {
#[inline]
fn poll( mut self: Pin< &mut Self >, cx: &mut Context ) -> Poll< Self::Output > {
- // TODO is this unwrap correct ?
+ // We unwrap here because an Error value indicates a significant bug in this code.
self.receiver.poll_unpin( cx ).map( |x| x.unwrap() )
}
}
diff --git a/src/webapi/token_list.rs b/src/webapi/token_list.rs
index c1eead02..04cbd736 100644
--- a/src/webapi/token_list.rs
+++ b/src/webapi/token_list.rs
@@ -50,4 +50,9 @@ impl TokenList {
pub fn contains( &self, token: &str ) -> bool {
js!( return @{self}.contains( @{token} ); ).try_into().unwrap()
}
+
+ /// Returns `true` if the list contains no tokens.
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
diff --git a/src/webapi/typed_array.rs b/src/webapi/typed_array.rs
index 9b1702a7..63db1484 100644
--- a/src/webapi/typed_array.rs
+++ b/src/webapi/typed_array.rs
@@ -130,6 +130,11 @@ impl< T: ArrayKind > TypedArray< T > {
pub fn to_vec( &self ) -> Vec< T > {
T::from_typed_array( self )
}
+
+ /// Returns `true` if the buffer contains no elements.
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
impl< 'a, T: ArrayKind > From< &'a [T] > for TypedArray< T > {
diff --git a/src/webapi/web_socket.rs b/src/webapi/web_socket.rs
index 28782fbd..e55e6dd4 100644
--- a/src/webapi/web_socket.rs
+++ b/src/webapi/web_socket.rs
@@ -277,14 +277,14 @@ impl WebSocket {
}
}
-/// Errors thrown by `WebSocket::new`.
error_enum_boilerplate! {
+ /// Errors thrown by `WebSocket::new`.
CreationError,
SecurityError, SyntaxError
}
-/// Errors thrown by `WebSocket::close_with_status`.
error_enum_boilerplate! {
+ /// Errors thrown by `WebSocket::close_with_status`.
CloseError,
InvalidAccessError, SyntaxError
}
diff --git a/src/webapi/xml_http_request.rs b/src/webapi/xml_http_request.rs
index e57ab0bc..abe85584 100644
--- a/src/webapi/xml_http_request.rs
+++ b/src/webapi/xml_http_request.rs
@@ -68,6 +68,12 @@ error_enum_boilerplate! {
InvalidAccessError
}
+impl Default for XmlHttpRequest {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
impl XmlHttpRequest {
/// Creates new `XmlHttpRequest`.
// https://xhr.spec.whatwg.org/#ref-for-dom-xmlhttprequest
diff --git a/src/webcore/array.rs b/src/webcore/array.rs
index 32461ca0..af6db162 100644
--- a/src/webcore/array.rs
+++ b/src/webcore/array.rs
@@ -14,6 +14,11 @@ impl Array {
return @{self}.length;
).try_into().unwrap()
}
+
+ /// Returns `true` if the array has no elements.
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
impl From< Array > for Vec< Value > {
diff --git a/src/webcore/executor.rs b/src/webcore/executor.rs
index 77ba6c5d..94f08a85 100644
--- a/src/webcore/executor.rs
+++ b/src/webcore/executor.rs
@@ -254,7 +254,7 @@ impl EventLoopExecutor {
let queue = Rc::new( EventLoopQueue {
inner: RefCell::new( EventLoopInner {
- queue: queue,
+ queue,
past_sum: 0,
past_length: 0,
shrink_counter: 0,
diff --git a/src/webcore/ffi/wasm_bindgen.rs b/src/webcore/ffi/wasm_bindgen.rs
index c8abfd72..3b69a78d 100644
--- a/src/webcore/ffi/wasm_bindgen.rs
+++ b/src/webcore/ffi/wasm_bindgen.rs
@@ -64,15 +64,15 @@ pub fn initialize() {
fn wasm_bindgen_initialize(
memory: JsValue,
table: JsValue,
- alloc: &Closure< Fn( usize ) -> *mut u8 >,
- free: &Closure< Fn( *mut u8, usize ) >
+ alloc: &Closure< dyn Fn( usize ) -> *mut u8 >,
+ free: &Closure< dyn Fn( *mut u8, usize ) >
) -> JsValue;
}
let memory = wasm_bindgen::memory();
let table = wasm_bindgen::function_table();
- let alloc = Closure::wrap( Box::new( alloc ) as Box< Fn( usize ) -> *mut u8 > );
- let free = Closure::wrap( Box::new( free ) as Box< Fn( *mut u8, usize ) > );
+ let alloc = Closure::wrap( Box::new( alloc ) as Box< dyn Fn( usize ) -> *mut u8 > );
+ let free = Closure::wrap( Box::new( free ) as Box< dyn Fn( *mut u8, usize ) > );
unsafe {
let module = wasm_bindgen_initialize( memory, table, &alloc, &free );
MODULE = Module( Some( module ) );
diff --git a/src/webcore/global_arena.rs b/src/webcore/global_arena.rs
index 79bea4b5..0ca831a5 100644
--- a/src/webcore/global_arena.rs
+++ b/src/webcore/global_arena.rs
@@ -4,19 +4,19 @@ use std::marker::PhantomData;
use webcore::value::Value;
use webcore::serialization::{JsSerialize, SerializedValue};
-struct GlobalArena {
- memory: *mut u8,
+struct GlobalArena {
+ memory: *mut T,
capacity: usize,
length: usize
}
-static mut VALUE_ARENA: GlobalArena = GlobalArena {
- memory: 0 as *mut u8,
+static mut VALUE_ARENA: GlobalArena = GlobalArena {
+ memory: 0 as *mut Value,
capacity: 0,
length: 0
};
-static mut ARENA: GlobalArena = GlobalArena {
+static mut ARENA: GlobalArena = GlobalArena {
memory: 0 as *mut u8,
capacity: 0,
length: 0
@@ -44,7 +44,7 @@ impl< 'a, T: 'a > RelativeSlice< 'a, T > {
pub unsafe fn append( &mut self, value: T ) {
debug_assert!( self.tail + mem::size_of::< T >() <= self.offset + self.length * mem::size_of::< T >() );
- let pointer = ARENA.memory.offset( self.tail as isize ) as *mut T;
+ let pointer = ARENA.memory.add( self.tail ) as *mut T;
mem::forget( mem::replace( &mut *pointer, value ) );
self.tail += mem::size_of::< T >();
}
@@ -53,10 +53,11 @@ impl< 'a, T: 'a > RelativeSlice< 'a, T > {
#[doc(hidden)]
pub fn serialize_value< 'a >( value: Value ) -> SerializedValue< 'a > {
unsafe {
+ // If I understand this correctly, because Vec is doing all the allocating when the type parameter is `Value`, it will always allocate correctly `Value`-aligned pointers, even though we're casting back and forth.
let mut vec = Vec::from_raw_parts( VALUE_ARENA.memory as *mut Value, VALUE_ARENA.length, VALUE_ARENA.capacity );
vec.push( value );
let pointer = vec.last().unwrap() as *const Value;
- VALUE_ARENA.memory = vec.as_mut_ptr() as *mut u8;
+ VALUE_ARENA.memory = vec.as_mut_ptr();
VALUE_ARENA.length = vec.len();
VALUE_ARENA.capacity = vec.capacity();
mem::forget( vec );
@@ -69,7 +70,7 @@ pub fn serialize_value< 'a >( value: Value ) -> SerializedValue< 'a > {
pub fn reserve< 'a, T >( length: usize ) -> RelativeSlice< 'a, T > {
unsafe {
let offset = reserve_impl( length * mem::size_of::< T >(), mem::align_of::< T >() );
- debug_assert_eq!( ARENA.memory.offset( offset as isize ) as usize % mem::align_of::< T >(), 0 );
+ debug_assert_eq!( ARENA.memory.add( offset ) as usize % mem::align_of::< T >(), 0 );
RelativeSlice { offset, length, tail: offset, phantom: PhantomData }
}
@@ -108,6 +109,7 @@ pub struct ArenaRestorePoint {
impl ArenaRestorePoint {
#[doc(hidden)]
+ #[allow(clippy::new_without_default)]
#[inline]
pub fn new() -> Self {
unsafe {
@@ -128,9 +130,9 @@ impl Drop for ArenaRestorePoint {
debug_assert!( VALUE_ARENA.length >= self.value_arena_length );
let count = VALUE_ARENA.length - self.value_arena_length;
if count > 0 {
- let mut vec = Vec::from_raw_parts( VALUE_ARENA.memory as *mut Value, VALUE_ARENA.length, VALUE_ARENA.capacity );
+ let mut vec = Vec::from_raw_parts( VALUE_ARENA.memory, VALUE_ARENA.length, VALUE_ARENA.capacity );
vec.truncate( self.value_arena_length );
- VALUE_ARENA.memory = vec.as_mut_ptr() as *mut u8;
+ VALUE_ARENA.memory = vec.as_mut_ptr();
VALUE_ARENA.length = vec.len();
VALUE_ARENA.capacity = vec.capacity();
mem::forget( vec );
@@ -141,7 +143,7 @@ impl Drop for ArenaRestorePoint {
#[cfg(test)]
mod tests {
- use super::{ARENA, VALUE_ARENA, GlobalArena};
+ use super::{ARENA, VALUE_ARENA, GlobalArena, Value};
unsafe fn clear() {
// This will leak, but in tests we don't care.
@@ -152,7 +154,7 @@ mod tests {
};
VALUE_ARENA = GlobalArena {
- memory: 0 as *mut u8,
+ memory: 0 as *mut Value,
capacity: 0,
length: 0
};
@@ -197,4 +199,22 @@ mod tests {
assert_eq!( ARENA.capacity, capacity );
}
}
+
+ // #[test]
+ // fn tests_are_working() {
+ // unsafe {
+ // clear();
+ // use webcore::try_from::TryInto;
+ // let message = "Hello, 世界!";
+ // println!("{}", message);
+ // let result = js! {
+ // return 2 + 2 * 2;
+ // };
+
+ // println!( "2 + 2 * 2 = {:?}", result );
+ // let j = js!{return false;};
+ // dbg!(j);
+ // assert!(false);
+ // }
+ // }
}
diff --git a/src/webcore/macros.rs b/src/webcore/macros.rs
index 933825c4..f9b4f879 100644
--- a/src/webcore/macros.rs
+++ b/src/webcore/macros.rs
@@ -132,7 +132,7 @@ macro_rules! _js_impl {
let restore_point = $crate::private::ArenaRestorePoint::new();
$crate::_js_impl!( @serialize [$($args)*] [$($arg_names)*] );
- #[allow(unused_unsafe, unused_parens)]
+ #[allow(unused_unsafe, unused_parens, clippy::too_many_arguments)]
let result = unsafe {
$crate::_js_impl!(
@if no_return in [$($flags)*] {{
@@ -255,14 +255,14 @@ macro_rules! __js_serializable_boilerplate {
(($($impl_arg:tt)*) ($($kind_arg:tt)*) ($($bounds:tt)*)) => {
impl< $($impl_arg)* > $crate::private::JsSerializeOwned for $($kind_arg)* where $($bounds)* {
#[inline]
- fn into_js_owned< '_a >( value: &'_a mut Option< Self > ) -> $crate::private::SerializedValue< '_a > {
+ fn into_js_owned( value: &mut Option< Self > ) -> $crate::private::SerializedValue {
$crate::private::JsSerialize::_into_js( value.as_ref().unwrap() )
}
}
impl< '_r, $($impl_arg)* > $crate::private::JsSerializeOwned for &'_r $($kind_arg)* where $($bounds)* {
#[inline]
- fn into_js_owned< '_a >( value: &'_a mut Option< Self > ) -> $crate::private::SerializedValue< '_a > {
+ fn into_js_owned( value: &mut Option< Self > ) -> $crate::private::SerializedValue {
$crate::private::JsSerialize::_into_js( value.unwrap() )
}
}
@@ -485,10 +485,10 @@ macro_rules! error_enum_boilerplate {
impl ::webcore::serialization::JsSerialize for $error_name {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> ::webcore::serialization::SerializedValue< 'a > {
+ fn _into_js( &self ) -> ::webcore::serialization::SerializedValue {
let reference: &::webcore::value::Reference = match self {
$(
- &$error_name::$variant( ref variant ) => variant.as_ref(),
+ $error_name::$variant( ref variant ) => variant.as_ref(),
)+
};
diff --git a/src/webcore/number.rs b/src/webcore/number.rs
index 0216d3d1..578e6f3c 100644
--- a/src/webcore/number.rs
+++ b/src/webcore/number.rs
@@ -5,9 +5,10 @@ use std::error;
use std::fmt;
use webcore::try_from::TryFrom;
-// 2^53 - 1
-const MAX_SAFE_INTEGER_F64: i64 = 9007199254740991;
-const MIN_SAFE_INTEGER_F64: i64 = -9007199254740991;
+#[allow(clippy::unreadable_literal)]
+const MAX_SAFE_INTEGER_F64: i64 = 9007199254740991;//(2_i64.pow(53)) - 1;
+#[allow(clippy::unreadable_literal)]
+const MIN_SAFE_INTEGER_F64: i64 = -9007199254740991;//-((2_i64.pow(53)) - 1);
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Storage {
@@ -242,7 +243,9 @@ macro_rules! i32_to_big_unsigned_integer {
macro_rules! f64_to_integer {
($value:expr, $kind:tt) => {{
- if $value.floor() != $value {
+ #[allow(clippy::float_cmp)] // I find integer checking to be a perfectly reasonable reason to compare floats
+ let comparison = $value.floor() != $value;
+ if comparison {
return Err( ConversionError::NotAnInteger );
}
diff --git a/src/webcore/object.rs b/src/webcore/object.rs
index 745fff50..b2052d6b 100644
--- a/src/webcore/object.rs
+++ b/src/webcore/object.rs
@@ -44,6 +44,11 @@ impl Object {
pub fn to_iter( &self ) -> impl ExactSizeIterator < Item = ( String, Value ) > {
deserialize_object_to_iter( self.as_ref() )
}
+
+ /// Returns `true` if object has no elements.
+ pub fn is_empty( &self ) -> bool {
+ self.len() == 0
+ }
}
impl From< Object > for BTreeMap< String, Value > {
@@ -64,19 +69,19 @@ impl< 'a > From< &'a mut Object > for BTreeMap< String, Value > {
}
}
-impl From< Object > for HashMap< String, Value > {
+impl< S: std::hash::BuildHasher + Default > From< Object > for HashMap< String, Value, S > {
fn from( object: Object ) -> Self {
deserialize_object( &object.0, |iter| iter.collect() )
}
}
-impl< 'a > From< &'a Object > for HashMap< String, Value > {
+impl< 'a, S: std::hash::BuildHasher + Default > From< &'a Object > for HashMap< String, Value, S > {
fn from( object: &'a Object ) -> Self {
deserialize_object( &object.0, |iter| iter.collect() )
}
}
-impl< 'a > From< &'a mut Object > for HashMap< String, Value > {
+impl< 'a, S: std::hash::BuildHasher + Default > From< &'a mut Object > for HashMap< String, Value, S > {
fn from( object: &'a mut Object ) -> Self {
deserialize_object( &object.0, |iter| iter.collect() )
}
@@ -112,16 +117,16 @@ impl< 'a, K, V > From< &'a mut BTreeMap< K, V > > for Object where K: AsRef< str
}
}
-impl< K, V > From< HashMap< K, V > > for Object where K: AsRef< str > + Hash + Eq, V: JsSerialize {
+impl< K, V, S: std::hash::BuildHasher > From< HashMap< K, V, S > > for Object where K: AsRef< str > + Hash + Eq, V: JsSerialize {
#[inline]
- fn from( value: HashMap< K, V > ) -> Self {
+ fn from( value: HashMap< K, V, S > ) -> Self {
(&value).into()
}
}
-impl< 'a, K, V > From< &'a HashMap< K, V > > for Object where K: AsRef< str > + Hash + Eq, V: JsSerialize {
+impl< 'a, K, V, S: std::hash::BuildHasher > From< &'a HashMap< K, V, S > > for Object where K: AsRef< str > + Hash + Eq, V: JsSerialize {
#[inline]
- fn from( value: &'a HashMap< K, V > ) -> Self {
+ fn from( value: &'a HashMap< K, V, S > ) -> Self {
// TODO: Do something more efficient here?
let value = js! {
return @{value};
@@ -134,10 +139,10 @@ impl< 'a, K, V > From< &'a HashMap< K, V > > for Object where K: AsRef< str > +
}
}
-impl< 'a, K: Hash + Eq, V > From< &'a mut HashMap< K, V > > for Object where K: AsRef< str >, V: JsSerialize {
+impl< 'a, K: Hash + Eq, V, S: std::hash::BuildHasher > From< &'a mut HashMap< K, V, S > > for Object where K: AsRef< str >, V: JsSerialize {
#[inline]
- fn from( value: &'a mut HashMap< K, V > ) -> Self {
- let value: &HashMap< K, V > = value;
+ fn from( value: &'a mut HashMap< K, V, S > ) -> Self {
+ let value: &HashMap< K, V, S > = value;
value.into()
}
}
@@ -157,12 +162,12 @@ impl< E: Into< ConversionError >, V: TryFrom< Value, Error = E > > TryFrom< Obje
}
}
-impl< E: Into< ConversionError >, V: TryFrom< Value, Error = E > > TryFrom< Object > for HashMap< String, V > {
+impl< E: Into< ConversionError >, V: TryFrom< Value, Error = E >, S: std::hash::BuildHasher + Default > TryFrom< Object > for HashMap< String, V, S > {
type Error = ConversionError;
fn try_from( object: Object ) -> Result< Self, Self::Error > {
- deserialize_object( object.as_ref(), |deserializer| -> Result< HashMap< String, V >, E > {
- let mut output = HashMap::with_capacity( deserializer.len() );
+ deserialize_object( object.as_ref(), |deserializer| -> Result< HashMap< String, V, S >, E > {
+ let mut output = HashMap::with_capacity_and_hasher( deserializer.len(), Default::default() );
for (key, value) in deserializer {
output.insert( key, value.try_into()? );
}
diff --git a/src/webcore/promise.rs b/src/webcore/promise.rs
index 5e280d4d..4c20dd21 100644
--- a/src/webcore/promise.rs
+++ b/src/webcore/promise.rs
@@ -293,11 +293,7 @@ impl Promise {
PromiseFuture {
future: receiver,
_done_handle: self.done( |value| {
- // TODO is this correct ?
- match sender.send( value ) {
- Ok( _ ) => {},
- Err( _ ) => {},
- };
+ let _ = sender.send( value );
} ),
}
}
@@ -311,6 +307,7 @@ impl< T, E > TypedPromise< T, E >
where T: TryFrom< Value >,
E: TryFrom< Value >
{
+ #[allow(dead_code)]
#[inline]
pub(crate) fn new( promise: Promise ) -> Self {
TypedPromise( promise, PhantomData )
diff --git a/src/webcore/promise_future.rs b/src/webcore/promise_future.rs
index d562eec9..70f6638b 100644
--- a/src/webcore/promise_future.rs
+++ b/src/webcore/promise_future.rs
@@ -30,11 +30,9 @@ use super::promise::{Promise, DoneHandle};
/// ```rust
/// use stdweb::spawn_local;
///
-/// fn main() {
-/// spawn_local(
-/// create_some_future()
-/// );
-/// }
+/// spawn_local(
+/// create_some_future()
+/// );
/// ```
///
/// If you want to retrieve the return value of the Future, you can use the various asynchronous
@@ -46,14 +44,12 @@ use super::promise::{Promise, DoneHandle};
/// use stdweb::spawn_local;
/// use futures::future::FutureExt;
///
-/// fn main() {
-/// spawn_local(
-/// create_some_future()
-/// .map(|x| {
-/// println!("Future finished with value: {:#?}", x);
-/// })
-/// );
-/// }
+/// spawn_local(
+/// create_some_future()
+/// .map(|x| {
+/// println!("Future finished with value: {:#?}", x);
+/// })
+/// );
/// ```
///
/// 2. However, some Futures return `Result`, and in that case you will need to deal with the `Result` somehow.
@@ -70,15 +66,13 @@ use super::promise::{Promise, DoneHandle};
/// use stdweb::spawn_local;
/// use futures::future::TryFutureExt;
///
-/// fn main() {
-/// spawn_local(
-/// create_some_future()
-/// .map_ok(|x| {
-/// println!("Future finished with value: {:#?}", x);
-/// })
-/// .unwrap_or_else(|e| handle_error_somehow(e))
-/// );
-/// }
+/// spawn_local(
+/// create_some_future()
+/// .map_ok(|x| {
+/// println!("Future finished with value: {:#?}", x);
+/// })
+/// .unwrap_or_else(|e| handle_error_somehow(e))
+/// );
/// ```
///
/// It is very common to want to print the errors to the console, and so as a convenience you can use the [`unwrap_future`](fn.unwrap_future.html) function:
@@ -87,14 +81,12 @@ use super::promise::{Promise, DoneHandle};
/// use stdweb::{spawn_local, unwrap_future};
/// use futures::future::TryFutureExt;
///
-/// fn main() {
-/// spawn_local(
-/// unwrap_future(create_some_future()
-/// .map_ok(|x| {
-/// println!("Future finished with value: {:#?}", x);
-/// }))
-/// );
-/// }
+/// spawn_local(
+/// unwrap_future(create_some_future()
+/// .map_ok(|x| {
+/// println!("Future finished with value: {:#?}", x);
+/// }))
+/// );
/// ```
///
/// If you don't need the return value from the Future, then it is even easier, since you don't need
@@ -103,11 +95,9 @@ use super::promise::{Promise, DoneHandle};
/// ```rust
/// use stdweb::{spawn_local, unwrap_future};
///
-/// fn main() {
-/// spawn_local(
-/// unwrap_future(create_some_future())
-/// );
-/// }
+/// spawn_local(
+/// unwrap_future(create_some_future())
+/// );
/// ```
#[inline]
pub fn spawn_local< F >( future: F ) where F: Future< Output = () > + 'static {
diff --git a/src/webcore/reference_type.rs b/src/webcore/reference_type.rs
index f5c3a113..80803364 100644
--- a/src/webcore/reference_type.rs
+++ b/src/webcore/reference_type.rs
@@ -6,5 +6,7 @@ use webcore::try_from::TryFrom;
pub trait ReferenceType: AsRef< Reference > + InstanceOf + TryFrom< Value > + TryFrom< Reference > {
/// Converts a given reference into a concrete reference-like wrapper.
/// Doesn't do any type checking; highly unsafe to use!
+ /// # Safety
+ /// This function is only safe so long as the given reference is an instance of the JS type the implementor claims to wrap.
unsafe fn from_reference_unchecked( reference: Reference ) -> Self;
}
diff --git a/src/webcore/serialization.rs b/src/webcore/serialization.rs
index 4f97d058..5fb46432 100644
--- a/src/webcore/serialization.rs
+++ b/src/webcore/serialization.rs
@@ -58,7 +58,7 @@ impl Default for Tag {
#[doc(hidden)]
pub trait JsSerializeOwned: Sized {
- fn into_js_owned< 'a >( value: &'a mut Option< Self > ) -> SerializedValue< 'a >;
+ fn into_js_owned( value: &mut Option< Self > ) -> SerializedValue;
}
/// A trait for types which can be serialized through the `js!` macro.
@@ -67,7 +67,7 @@ pub trait JsSerializeOwned: Sized {
/// to be used inside generic code for specifying trait bounds.
pub trait JsSerialize {
#[doc(hidden)]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a >;
+ fn _into_js( & self ) -> SerializedValue;
}
// This is a generic structure for serializing every JavaScript value.
@@ -411,12 +411,16 @@ macro_rules! untagged_boilerplate {
impl< 'a > From< $untagged_type > for SerializedValue< 'a > {
#[inline]
fn from( untagged: $untagged_type ) -> Self {
+ let mut value = SerializedValue {
+ data_1: 0,
+ data_2: 0,
+ tag: $tag,
+ phantom: PhantomData,
+ };
unsafe {
- let mut value: SerializedValue = mem::uninitialized();
- *(&mut value as *mut SerializedValue as *mut $untagged_type) = untagged;
- value.tag = $tag;
- value
+ *(&mut value as *mut _ as *mut $untagged_type) = untagged;
}
+ return value;
}
}
@@ -477,7 +481,7 @@ impl< 'a > SerializedValue< 'a > {
impl JsSerialize for () {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedUndefined.into()
}
}
@@ -487,7 +491,7 @@ __js_serializable_boilerplate!( () );
impl JsSerialize for Undefined {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedUndefined.into()
}
}
@@ -497,7 +501,7 @@ __js_serializable_boilerplate!( Undefined );
impl JsSerialize for Null {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedNull.into()
}
}
@@ -507,7 +511,7 @@ __js_serializable_boilerplate!( Null );
impl JsSerialize for Symbol {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedSymbol {
id: self.0
}.into()
@@ -519,7 +523,7 @@ __js_serializable_boilerplate!( Symbol );
impl JsSerialize for Reference {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedReference {
refid: self.as_raw()
}.into()
@@ -531,7 +535,7 @@ __js_serializable_boilerplate!( Reference );
impl JsSerialize for bool {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
if *self {
SerializedUntaggedTrue {}.into()
} else {
@@ -545,7 +549,7 @@ __js_serializable_boilerplate!( bool );
impl JsSerialize for str {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedString {
pointer: self.as_ptr() as u32,
length: self.len() as u32
@@ -558,7 +562,7 @@ __js_serializable_boilerplate!( impl< 'a > for &'a str );
impl JsSerialize for String {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
self.as_str()._into_js()
}
}
@@ -568,7 +572,7 @@ __js_serializable_boilerplate!( String );
impl JsSerialize for i8 {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedI32 {
value: *self as i32
}.into()
@@ -580,7 +584,7 @@ __js_serializable_boilerplate!( i8 );
impl JsSerialize for i16 {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedI32 {
value: *self as i32
}.into()
@@ -592,7 +596,7 @@ __js_serializable_boilerplate!( i16 );
impl JsSerialize for i32 {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedI32 {
value: *self
}.into()
@@ -604,7 +608,7 @@ __js_serializable_boilerplate!( i32 );
impl JsSerialize for u8 {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedI32 {
value: *self as i32
}.into()
@@ -616,7 +620,7 @@ __js_serializable_boilerplate!( u8 );
impl JsSerialize for u16 {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedI32 {
value: *self as i32
}.into()
@@ -628,7 +632,7 @@ __js_serializable_boilerplate!( u16 );
impl JsSerialize for u32 {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedF64 {
value: *self as f64
}.into()
@@ -640,7 +644,7 @@ __js_serializable_boilerplate!( u32 );
impl JsSerialize for f32 {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedF64 {
value: *self as f64
}.into()
@@ -652,7 +656,7 @@ __js_serializable_boilerplate!( f32 );
impl JsSerialize for f64 {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
SerializedUntaggedF64 {
value: *self
}.into()
@@ -664,7 +668,7 @@ __js_serializable_boilerplate!( f64 );
impl JsSerialize for Number {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
use webcore::number::{Storage, get_storage};
match *get_storage( self ) {
Storage::I32( ref value ) => value._into_js(),
@@ -678,7 +682,7 @@ __js_serializable_boilerplate!( Number );
impl< T: JsSerialize > JsSerialize for Option< T > {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
if let Some( value ) = self.as_ref() {
value._into_js()
} else {
@@ -692,7 +696,7 @@ __js_serializable_boilerplate!( impl< T > for Option< T > where T: JsSerialize )
impl< T: JsSerialize > JsSerialize for OptionalArg< T > {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
if let OptionalArg::Some( value ) = self.as_ref() {
value._into_js()
} else {
@@ -706,7 +710,7 @@ __js_serializable_boilerplate!( impl< T > for OptionalArg< T > where T: JsSerial
impl< T: JsSerialize > JsSerialize for [T] {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
let mut output = global_arena::reserve( self.len() );
for value in self {
unsafe {
@@ -726,7 +730,7 @@ __js_serializable_boilerplate!( impl< 'a, T > for &'a [T] where T: JsSerialize )
impl< T: JsSerialize > JsSerialize for Vec< T > {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
self.as_slice()._into_js()
}
}
@@ -753,26 +757,26 @@ fn object_into_js< 'a, K: AsRef< str >, V: 'a + JsSerialize, I: Iterator< Item =
impl< K: AsRef< str >, V: JsSerialize > JsSerialize for BTreeMap< K, V > {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( & self ) -> SerializedValue {
object_into_js( self.iter() )
}
}
__js_serializable_boilerplate!( impl< K, V > for BTreeMap< K, V > where K: AsRef< str >, V: JsSerialize );
-impl< K: AsRef< str > + Eq + Hash, V: JsSerialize > JsSerialize for HashMap< K, V > {
+impl< K: AsRef< str > + Eq + Hash, V: JsSerialize, S: std::hash::BuildHasher > JsSerialize for HashMap< K, V, S > {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( &self ) -> SerializedValue {
object_into_js( self.iter() )
}
}
-__js_serializable_boilerplate!( impl< K, V > for HashMap< K, V > where K: AsRef< str > + Eq + Hash, V: JsSerialize );
+__js_serializable_boilerplate!( impl< K, V, S > for HashMap< K, V, S > where K: AsRef< str > + Eq + Hash, V: JsSerialize, S: std::hash::BuildHasher );
impl JsSerialize for Value {
#[doc(hidden)]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( &self ) -> SerializedValue {
match *self {
Value::Undefined => SerializedUntaggedUndefined.into(),
Value::Null => SerializedUntaggedNull.into(),
@@ -792,7 +796,7 @@ macro_rules! impl_for_unsafe_typed_array {
impl< 'r > JsSerialize for UnsafeTypedArray< 'r, $ty > {
#[doc(hidden)]
#[inline]
- fn _into_js< 'a >( &'a self ) -> SerializedValue< 'a > {
+ fn _into_js( &self ) -> SerializedValue {
SerializedUntaggedUnsafeTypedArray {
pointer: self.0.as_ptr() as u32 / mem::size_of::< $ty >() as u32,
length: self.0.len() as u32,
@@ -822,7 +826,7 @@ pub struct NonFunctionTag;
impl< T: JsSerialize > JsSerializeOwned for Newtype< (NonFunctionTag, ()), T > {
#[inline]
- fn into_js_owned< 'x >( value: &'x mut Option< Self > ) -> SerializedValue< 'x > {
+ fn into_js_owned( value: &mut Option< Self > ) -> SerializedValue {
JsSerialize::_into_js( value.as_ref().unwrap().as_ref() )
}
}
@@ -864,6 +868,7 @@ macro_rules! impl_for_fn_and_modifier {
let mut arguments = arguments.drain( .. );
let mut nth_argument = 0;
$(
+ #[allow(clippy::match_wild_err_arm)]
let $kind = match arguments.next().unwrap().try_into() {
Ok( value ) => value,
Err( _ ) => {
@@ -903,7 +908,7 @@ macro_rules! impl_for_fn_and_modifier {
where F: $trait< ($($kind,)*) > + 'static, F::Output: JsSerializeOwned
{
#[inline]
- fn into_js_owned< 'a >( value: &'a mut Option< Self > ) -> SerializedValue< 'a > {
+ fn into_js_owned( value: &mut Option< Self > ) -> SerializedValue {
let $wrapped = value.take().unwrap().unwrap_newtype();
let callback: *mut F = Box::into_raw( Box::new( $unwrap ) );
let adapter_pointer = >::funcall_adapter;
@@ -920,7 +925,7 @@ macro_rules! impl_for_fn_and_modifier {
where F: $trait< ($($kind,)*) > + 'static, F::Output: JsSerializeOwned
{
#[inline]
- fn into_js_owned< 'a >( value: &'a mut Option< Self > ) -> SerializedValue< 'a > {
+ fn into_js_owned( value: &mut Option< Self > ) -> SerializedValue {
if let Some( $wrapped ) = value.take().unwrap().unwrap_newtype() {
let callback: *mut F = Box::into_raw( Box::new( $unwrap ) );
let adapter_pointer = as FuncallAdapter< F > >::funcall_adapter;
@@ -976,14 +981,14 @@ loop_through_identifiers!( impl_for_fn );
impl< 'a, T: ?Sized + JsSerialize > JsSerialize for &'a T {
#[doc(hidden)]
#[inline]
- fn _into_js< 'x >( &'x self ) -> SerializedValue< 'x > {
+ fn _into_js( &self ) -> SerializedValue {
T::_into_js( *self )
}
}
impl JsSerialize for ConversionError {
#[doc(hidden)]
- fn _into_js< 'x >( &'x self ) -> SerializedValue< 'x > {
+ fn _into_js( &self ) -> SerializedValue {
let type_error: TypeError = self.into();
let reference: Reference = type_error.into();
let value: Value = reference.into();
diff --git a/src/webcore/type_name.rs b/src/webcore/type_name.rs
index 107061c0..02d143b0 100644
--- a/src/webcore/type_name.rs
+++ b/src/webcore/type_name.rs
@@ -1,9 +1,7 @@
#[cfg(rust_nightly)]
pub fn type_name_opt< T >() -> Option< &'static str > {
use std::intrinsics;
- let name = unsafe {
- intrinsics::type_name::< T >()
- };
+ let name = intrinsics::type_name::< T >();
Some( name )
}
diff --git a/src/webcore/unsafe_typed_array.rs b/src/webcore/unsafe_typed_array.rs
index 0d3bf986..ee6e352f 100644
--- a/src/webcore/unsafe_typed_array.rs
+++ b/src/webcore/unsafe_typed_array.rs
@@ -5,6 +5,8 @@ use std::fmt;
///
/// The only thing you can do with this is to pass it to the `js!` macro.
///
+/// # Safety
+///
/// Using this is **highly unsafe**! After you pass it to the `js!` macro
/// you **must** use it **before** triggering any Rust code whatsoever,
/// either directly or indirectly. Breaking this rule will result
@@ -37,6 +39,10 @@ impl< 'a, T > UnsafeTypedArray< 'a, T > {
/// Even though this function is marked as `unsafe`
/// the unsafely only comes into play after you
/// pass it to the `js!` macro.
+ ///
+ /// # Safety
+ ///
+ /// See safety section of type documentation
#[inline]
pub unsafe fn new( slice: &'a [T] ) -> Self {
UnsafeTypedArray( slice )
diff --git a/src/webcore/value.rs b/src/webcore/value.rs
index 70da8b75..495b0179 100644
--- a/src/webcore/value.rs
+++ b/src/webcore/value.rs
@@ -2,7 +2,6 @@ use std::collections::{BTreeMap, HashMap};
use std::hash::Hash;
use std::fmt;
use std::error;
-use std::mem;
use std::borrow::Cow;
use webcore::void::Void;
use webcore::try_from::{TryFrom, TryInto};
@@ -66,10 +65,13 @@ impl PartialEq for Reference {
fn eq( &self, other: &Reference ) -> bool {
let result = self.0 == other.0;
- debug_assert_eq!( {
- let real_result: bool = js!( return @{self} === @{other}; ).try_into().unwrap();
- real_result
- }, result );
+ if cfg!(debug_assertions)
+ {
+ assert_eq!( {
+ let real_result: bool = js!( return @{self} === @{other}; ).try_into().unwrap();
+ real_result
+ }, result );
+ }
result
}
@@ -234,7 +236,7 @@ impl Value {
match *self {
Value::Reference( ref reference ) if Object::instance_of( reference ) => {
unsafe {
- Some( mem::transmute( reference ) )
+ Some( &*(reference as *const Reference as *const Object) )
}
},
_ => None
@@ -247,7 +249,7 @@ impl Value {
match *self {
Value::Reference( ref reference ) if Array::instance_of( reference ) => {
unsafe {
- Some( mem::transmute( reference ) )
+ Some( &*(reference as *const Reference as *const Array) )
}
},
_ => None
@@ -285,6 +287,10 @@ impl Value {
/// the given type `T`; doesn't check whenever the reference is really of type `T`.
///
/// In cases where the value is not a `Reference` a `None` is returned.
+ ///
+ /// # Safety
+ ///
+ /// If the reference is not really of type `T`, behavior is undefined.
#[inline]
pub unsafe fn into_reference_unchecked< T: ReferenceType >( self ) -> Option< T > {
let reference: Option< Reference > = self.try_into().ok();
@@ -1008,7 +1014,7 @@ impl< E: Into< ConversionError >, V: TryFrom< Value, Error = E > > TryFrom< Valu
}
}
-impl< E: Into< ConversionError >, V: TryFrom< Value, Error = E > > TryFrom< Value > for HashMap< String, V > {
+impl< E: Into< ConversionError >, V: TryFrom< Value, Error = E >, S: ::std::hash::BuildHasher + Default > TryFrom< Value > for HashMap< String, V, S > {
type Error = ConversionError;
#[inline]