Repository: websockets-rs/rust-websocket (language: rust)

Issue:
Add clippy integration to the travis job
Would be cool to add [Manishearth/rust-clippy](https://github.com/Manishearth/rust-clippy) to the linting checks to catch silly mistakes.


Discussion / hints:

Fix patch:
diff --git a/.travis.yml b/.travis.yml
index c2410b8c54..439b4a83f7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,14 +1,19 @@
 language: rust
 rust: nightly
+
 before_script:
   - export PATH="$PATH:$HOME/.cargo/bin"
+
+install:
   - rustup component add rustfmt-preview
+  - rustup component add clippy-preview
 
 script:
-    - cargo fmt -- --check
-    - ./scripts/build-all.sh
-    - cargo test --features nightly
-    - cargo bench --features nightly
+  - cargo fmt -- --check
+  - cargo clippy --all-features -- -D clippy
+  - ./scripts/build-all.sh
+  - cargo test --features nightly
+  - cargo bench --features nightly
 
 after_success:
   - sudo apt-get install python-unittest2
diff --git a/README.md b/README.md
index 2325f14ffb..cde62dad37 100644
--- a/README.md
+++ b/README.md
@@ -65,6 +65,23 @@ To test the server implementation. The spec files are available [here](http://we
 
 The results of these tests are available [here](http://websockets-rs.github.io/rust-websocket/autobahn).
 
+## Contributing
+
+Before you make a PR be sure to run all the tests!
+
+```bash
+# install
+rustup component add rustfmt-preview
+rustup component add clippy-preview
+
+# test
+cargo +nightly fmt -- --check
+cargo +nightly clippy --all-features -- -D clippy
+cargo test --features nightly
+cargo bench --features nightly
+./scripts/build-all.sh
+```
+
 ## License
 
 ### The MIT License (MIT)
diff --git a/src/client/builder.rs b/src/client/builder.rs
index cd08745c72..6ac5766c16 100644
--- a/src/client/builder.rs
+++ b/src/client/builder.rs
@@ -148,7 +148,7 @@ impl<'u> ClientBuilder<'u> {
 
 	fn init(url: Cow<'u, Url>) -> Self {
 		ClientBuilder {
-			url: url,
+			url,
 			version: HttpVersion::Http11,
 			version_set: false,
 			key_set: false,
@@ -811,7 +811,7 @@ impl<'u> ClientBuilder<'u> {
 					));
 				}
 			},
-			Err(e) => return Err(e.into()),
+			Err(e) => return Err(e),
 		};
 
 		// connect a tcp stream
@@ -847,8 +847,7 @@ impl<'u> ClientBuilder<'u> {
 		}
 
 		// send request
-		let resource = self.url[Position::BeforePath..Position::AfterQuery].to_owned();
-		resource
+		self.url[Position::BeforePath..Position::AfterQuery].to_owned()
 	}
 
 	#[cfg(any(feature = "sync", feature = "async"))]
diff --git a/src/client/sync.rs b/src/client/sync.rs
index a2dc591fab..8d2545372b 100644
--- a/src/client/sync.rs
+++ b/src/client/sync.rs
@@ -126,8 +126,8 @@ where
 		in_mask: bool,
 	) -> Self {
 		Client {
-			headers: headers,
-			stream: stream,
+			headers,
+			stream,
 			sender: Sender::new(out_mask),    // true
 			receiver: Receiver::new(in_mask), // false
 		}
diff --git a/src/codec/ws.rs b/src/codec/ws.rs
index f0d065d1d2..0a87771a44 100644
--- a/src/codec/ws.rs
+++ b/src/codec/ws.rs
@@ -31,7 +31,7 @@ use ws::util::header::read_header;
 ///
 /// For those familiar with the protocol, this decides wether the data should be
 /// masked or not.
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub enum Context {
 	/// Set the codec to act in `Server` mode, used when
 	/// implementing a websocket server.
diff --git a/src/dataframe.rs b/src/dataframe.rs
index 08556b94a9..730ed55962 100644
--- a/src/dataframe.rs
+++ b/src/dataframe.rs
@@ -30,10 +30,10 @@ impl DataFrame {
 	/// Creates a new DataFrame.
 	pub fn new(finished: bool, opcode: Opcode, data: Vec<u8>) -> DataFrame {
 		DataFrame {
-			finished: finished,
+			finished,
 			reserved: [false; 3],
-			opcode: opcode,
-			data: data,
+			opcode,
+			data,
 		}
 	}
 
@@ -74,10 +74,10 @@ impl DataFrame {
 		};
 
 		Ok(DataFrame {
-			finished: finished,
-			reserved: reserved,
-			opcode: opcode,
-			data: data,
+			finished,
+			reserved,
+			opcode,
+			data,
 		})
 	}
 
diff --git a/src/header/extensions.rs b/src/header/extensions.rs
index 9ef7626bf4..de99fa0df3 100644
--- a/src/header/extensions.rs
+++ b/src/header/extensions.rs
@@ -8,7 +8,7 @@ use std::fmt;
 use std::ops::Deref;
 use std::str::FromStr;
 
-const INVALID_EXTENSION: &'static str = "Invalid Sec-WebSocket-Extensions extension name";
+const INVALID_EXTENSION: &str = "Invalid Sec-WebSocket-Extensions extension name";
 
 // TODO: check if extension name is valid according to spec
 
@@ -37,7 +37,7 @@ impl Extension {
 	/// Creates a new extension with the given name
 	pub fn new(name: String) -> Extension {
 		Extension {
-			name: name,
+			name,
 			params: Vec::new(),
 		}
 	}
@@ -88,10 +88,7 @@ pub struct Parameter {
 impl Parameter {
 	/// Creates a new parameter with the given name and value
 	pub fn new(name: String, value: Option<String>) -> Parameter {
-		Parameter {
-			name: name,
-			value: value,
-		}
+		Parameter { name, value }
 	}
 }
 
diff --git a/src/lib.rs b/src/lib.rs
index e625c926b8..7119c130f9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,9 @@
 #![warn(missing_docs)]
 #![cfg_attr(all(test, feature = "nightly"), feature(test))]
+#![cfg_attr(
+	feature = "cargo-clippy",
+	allow(write_with_newline, type_complexity, match_ref_pats)
+)]
 #![deny(unused_mut)]
 
 //! Rust-WebSocket is a WebSocket (RFC6455) library written in Rust.
diff --git a/src/message.rs b/src/message.rs
index c4bcaaa9a4..91bf14aa2c 100644
--- a/src/message.rs
+++ b/src/message.rs
@@ -10,7 +10,7 @@ use ws;
 use ws::dataframe::DataFrame as DataFrameTrait;
 use ws::util::bytes_to_string;
 
-const FALSE_RESERVED_BITS: &'static [bool; 3] = &[false; 3];
+const FALSE_RESERVED_BITS: &[bool; 3] = &[false; 3];
 
 /// Valid types of messages (in the default implementation)
 #[derive(Debug, Eq, PartialEq, Clone, Copy)]
@@ -51,7 +51,7 @@ impl<'a> Message<'a> {
 		Message {
 			opcode: code,
 			cd_status_code: status,
-			payload: payload,
+			payload,
 		}
 	}
 
@@ -119,6 +119,8 @@ impl<'a> Message<'a> {
 		Message::new(Type::Pong, None, data.into())
 	}
 
+	// TODO: change this to match conventions
+	#[cfg_attr(feature = "cargo-clippy", allow(wrong_self_convention))]
 	/// Convert a ping message to a pong, keeping the data.
 	/// This will fail if the original message is not a ping.
 	pub fn into_pong(&mut self) -> Result<(), ()> {
@@ -226,7 +228,7 @@ impl<'a> ws::Message for Message<'a> {
 			},
 			Some(Opcode::Binary) => Message::binary(data),
 			Some(Opcode::Close) => {
-				if data.len() > 0 {
+				if !data.is_empty() {
 					let status_code = (&data[..]).read_u16::<BigEndian>()?;
 					let reason = bytes_to_string(&data[2..])?;
 					Message::close_because(status_code, reason)
@@ -483,8 +485,8 @@ impl CloseData {
 	/// Create a new CloseData object
 	pub fn new(status_code: u16, reason: String) -> CloseData {
 		CloseData {
-			status_code: status_code,
-			reason: reason,
+			status_code,
+			reason,
 		}
 	}
 	/// Convert this into a vector of bytes
diff --git a/src/receiver.rs b/src/receiver.rs
index 5f667c63f0..658878b85e 100644
--- a/src/receiver.rs
+++ b/src/receiver.rs
@@ -84,7 +84,7 @@ impl Receiver {
 	pub fn new(mask: bool) -> Receiver {
 		Receiver {
 			buffer: Vec::new(),
-			mask: mask,
+			mask,
 		}
 	}
 }
diff --git a/src/sender.rs b/src/sender.rs
index a6031bab6b..0f748129ac 100644
--- a/src/sender.rs
+++ b/src/sender.rs
@@ -68,7 +68,7 @@ pub struct Sender {
 impl Sender {
 	/// Create a new WebSocketSender using the specified Writer.
 	pub fn new(mask: bool) -> Sender {
-		Sender { mask: mask }
+		Sender { mask }
 	}
 }
 
diff --git a/src/server/sync.rs b/src/server/sync.rs
index c85a4e652c..e3d43fadcf 100644
--- a/src/server/sync.rs
+++ b/src/server/sync.rs
@@ -155,7 +155,7 @@ impl WsServer<TlsAcceptor, TcpListener> {
 					stream: None,
 					parsed: None,
 					buffer: None,
-					error: e.into(),
+					error: HyperIntoWsError::Io(e),
 				})
 			}
 		};
@@ -178,7 +178,7 @@ impl WsServer<TlsAcceptor, TcpListener> {
 				stream: Some(s),
 				parsed: r,
 				buffer: b,
-				error: e.into(),
+				error: e,
 			}),
 		}
 	}
@@ -247,7 +247,7 @@ impl WsServer<NoTlsAcceptor, TcpListener> {
 				stream: Some(s),
 				parsed: r,
 				buffer: b,
-				error: e.into(),
+				error: e,
 			}),
 		}
 	}
diff --git a/src/server/upgrade/async.rs b/src/server/upgrade/async.rs
index 7d22bdc088..f094bd4bb3 100644
--- a/src/server/upgrade/async.rs
+++ b/src/server/upgrade/async.rs
@@ -226,7 +226,7 @@ where
 			}).and_then(|(m, s)| {
 				let FramedParts { inner, readbuf, .. } = s.into_parts();
 				if let Some(msg) = m {
-					match validate(&msg.subject.0, &msg.version, &msg.headers) {
+					match validate(&msg.subject.0, msg.version, &msg.headers) {
 						Ok(()) => Ok((msg, inner, readbuf)),
 						Err(e) => Err((inner, Some(msg), readbuf, e)),
 					}
@@ -239,9 +239,9 @@ where
 				}
 			}).map(|(m, stream, buffer)| WsUpgrade {
 				headers: Headers::new(),
-				stream: stream,
+				stream,
 				request: m,
-				buffer: buffer,
+				buffer,
 			});
 		Box::new(future)
 	}
diff --git a/src/server/upgrade/mod.rs b/src/server/upgrade/mod.rs
index d7174369ee..e81bcd2ded 100644
--- a/src/server/upgrade/mod.rs
+++ b/src/server/upgrade/mod.rs
@@ -239,14 +239,14 @@ impl From<::codec::http::HttpCodecError> for HyperIntoWsError {
 /// Check whether an incoming request is a valid WebSocket upgrade attempt.
 pub fn validate(
 	method: &Method,
-	version: &HttpVersion,
+	version: HttpVersion,
 	headers: &Headers,
 ) -> Result<(), HyperIntoWsError> {
 	if *method != Method::Get {
 		return Err(HyperIntoWsError::MethodNotGet);
 	}
 
-	if *version == HttpVersion::Http09 || *version == HttpVersion::Http10 {
+	if version == HttpVersion::Http09 || version == HttpVersion::Http10 {
 		return Err(HyperIntoWsError::UnsupportedHttpVersion);
 	}
 
diff --git a/src/server/upgrade/sync.rs b/src/server/upgrade/sync.rs
index a0031527a8..4dd9b78ebe 100644
--- a/src/server/upgrade/sync.rs
+++ b/src/server/upgrade/sync.rs
@@ -167,23 +167,19 @@ where
 		let request = parse_request(&mut reader);
 
 		let (stream, buf, pos, cap) = reader.into_parts();
-		let buffer = Some(Buffer {
-			buf: buf,
-			cap: cap,
-			pos: pos,
-		});
+		let buffer = Some(Buffer { buf, cap, pos });
 
 		let request = match request {
 			Ok(r) => r,
 			Err(e) => return Err((stream, None, buffer, e.into())),
 		};
 
-		match validate(&request.subject.0, &request.version, &request.headers) {
+		match validate(&request.subject.0, request.version, &request.headers) {
 			Ok(_) => Ok(WsUpgrade {
 				headers: Headers::new(),
-				stream: stream,
-				request: request,
-				buffer: buffer,
+				stream,
+				request,
+				buffer,
 			}),
 			Err(e) => Err((stream, Some(request), buffer, e)),
 		}
@@ -198,7 +194,7 @@ where
 	type Error = (S, Request, HyperIntoWsError);
 
 	fn into_ws(self) -> Result<Upgrade<Self::Stream>, Self::Error> {
-		match validate(&self.1.subject.0, &self.1.version, &self.1.headers) {
+		match validate(&self.1.subject.0, self.1.version, &self.1.headers) {
 			Ok(_) => Ok(WsUpgrade {
 				headers: Headers::new(),
 				stream: self.0,
@@ -257,7 +253,7 @@ impl<'a, 'b> IntoWs for HyperRequest<'a, 'b> {
 	type Error = (::hyper::server::Request<'a, 'b>, HyperIntoWsError);
 
 	fn into_ws(self) -> Result<Upgrade<Self::Stream>, Self::Error> {
-		if let Err(e) = validate(&self.0.method, &self.0.version, &self.0.headers) {
+		if let Err(e) = validate(&self.0.method, self.0.version, &self.0.headers) {
 			return Err((self.0, e));
 		}
 
@@ -269,15 +265,11 @@ impl<'a, 'b> IntoWs for HyperRequest<'a, 'b> {
 
 		Ok(Upgrade {
 			headers: Headers::new(),
-			stream: stream,
-			buffer: Some(Buffer {
-				buf: buf,
-				pos: pos,
-				cap: cap,
-			}),
+			stream,
+			buffer: Some(Buffer { buf, pos, cap }),
 			request: Incoming {
-				version: version,
-				headers: headers,
+				version,
+				headers,
 				subject: (method, uri),
 			},
 		})
diff --git a/src/ws/dataframe.rs b/src/ws/dataframe.rs
index 12ac2ceddb..2b6c13acc8 100644
--- a/src/ws/dataframe.rs
+++ b/src/ws/dataframe.rs
@@ -71,7 +71,7 @@ pub trait DataFrame {
 		let masking_key = if mask { Some(mask::gen_mask()) } else { None };
 
 		let header = dfh::DataFrameHeader {
-			flags: flags,
+			flags,
 			opcode: self.opcode() as u8,
 			mask: masking_key,
 			len: self.size() as u64,
diff --git a/src/ws/receiver.rs b/src/ws/receiver.rs
index 4e97dc5509..3a2ea771a5 100644
--- a/src/ws/receiver.rs
+++ b/src/ws/receiver.rs
@@ -32,13 +32,13 @@ pub trait Receiver: Sized {
 		R: Read,
 	{
 		DataFrameIterator {
-			reader: reader,
+			reader,
 			inner: self,
 		}
 	}
 
 	/// Reads a single message from this receiver.
-	fn recv_message<'m, R>(&mut self, reader: &mut R) -> WebSocketResult<Self::M>
+	fn recv_message<R>(&mut self, reader: &mut R) -> WebSocketResult<Self::M>
 	where
 		R: Read,
 	{
@@ -52,7 +52,7 @@ pub trait Receiver: Sized {
 		R: Read,
 	{
 		MessageIterator {
-			reader: reader,
+			reader,
 			inner: self,
 		}
 	}
diff --git a/src/ws/util/header.rs b/src/ws/util/header.rs
index b1d3782966..812da251df 100644
--- a/src/ws/util/header.rs
+++ b/src/ws/util/header.rs
@@ -81,9 +81,9 @@ where
 	let opcode = byte0 & 0x0F;
 
 	let len = match byte1 & 0x7F {
-		0...125 => (byte1 & 0x7F) as u64,
+		0...125 => u64::from(byte1 & 0x7F),
 		126 => {
-			let len = reader.read_u16::<BigEndian>()? as u64;
+			let len = u64::from(reader.read_u16::<BigEndian>()?);
 			if len <= 125 {
 				return Err(WebSocketError::DataFrameError("Invalid data frame length"));
 			}
@@ -124,10 +124,10 @@ where
 	};
 
 	Ok(DataFrameHeader {
-		flags: flags,
-		opcode: opcode,
-		mask: mask,
-		len: len,
+		flags,
+		opcode,
+		mask,
+		len,
 	})
 }
 
diff --git a/src/ws/util/mask.rs b/src/ws/util/mask.rs
index 7ad552ecac..802e39b3ca 100644
--- a/src/ws/util/mask.rs
+++ b/src/ws/util/mask.rs
@@ -17,7 +17,7 @@ impl<'w> Masker<'w> {
 	/// to be writer to.
 	pub fn new(key: [u8; 4], endpoint: &'w mut Write) -> Self {
 		Masker {
-			key: key,
+			key,
 			pos: 0,
 			end: endpoint,
 		}


Test patch: