From 0fd7abea33a598be754efd2de400c22082041790 Mon Sep 17 00:00:00 2001
From: James Munns <james.munns@gmail.com>
Date: Sun, 19 Jun 2016 15:19:52 +0200
Subject: [PATCH] Fix indentation (tabs-consistent), Include the response
 automatically if possible

---
 examples/client.rs            |   2 +-
 examples/client_and_server.rs |  14 ++--
 examples/server.rs            |  16 ++---
 src/client.rs                 |  28 ++++----
 src/lib.rs                    |   2 +-
 src/packet.rs                 | 123 +++++++++++++++++-----------------
 src/server.rs                 |  53 +++++++--------
 7 files changed, 118 insertions(+), 120 deletions(-)

diff --git a/examples/client.rs b/examples/client.rs
index aa3d135..865a56c 100644
--- a/examples/client.rs
+++ b/examples/client.rs
@@ -31,4 +31,4 @@ fn main() {
 			}
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/examples/client_and_server.rs b/examples/client_and_server.rs
index 39ba858..1d5fb6e 100644
--- a/examples/client_and_server.rs
+++ b/examples/client_and_server.rs
@@ -3,15 +3,15 @@ extern crate coap;
 use coap::packet::*;
 use coap::{CoAPServer, CoAPClient};
 
-fn request_handler(req: Packet) -> Option<Packet> {
+fn request_handler(req: Packet, response: Option<Packet>) -> Option<Packet> {
 	let uri_path = req.get_option(OptionType::UriPath).unwrap();
 
-	return match coap::packet::auto_response(req) {
-	Ok(mut response) => {
-		response.set_payload(uri_path.front().unwrap().clone());
-		Some(response)
-	},
-	Err(_) => None
+	return match response {
+		Some(mut packet) => {
+			packet.set_payload(uri_path.front().unwrap().clone());
+			Some(packet)
+		},
+		_ => None
     };
 }
 
diff --git a/examples/server.rs b/examples/server.rs
index cafd2a3..887e4ae 100644
--- a/examples/server.rs
+++ b/examples/server.rs
@@ -4,14 +4,14 @@ use std::io;
 use coap::packet::*;
 use coap::CoAPServer;
 
-fn request_handler(req: Packet) -> Option<Packet> {
-    return match coap::packet::auto_response(req) {
-        Ok(mut response) => {
-		response.set_payload(b"OK".to_vec());
-		Some(response)
-	},
-        Err(_) => None
-    };
+fn request_handler(_: Packet, response: Option<Packet>) -> Option<Packet> {
+	return match response {
+		Some(mut packet) => {
+			packet.set_payload(b"OK".to_vec());
+			Some(packet)
+		},
+		_ => None
+	};
 }
 
 fn main() {
diff --git a/src/client.rs b/src/client.rs
index 27407e5..84b8617 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -9,8 +9,8 @@ use packet::{Packet, PacketType, OptionType};
 const DEFAULT_RECEIVE_TIMEOUT: u64 = 5;  // 5s
 
 pub struct CoAPClient {
-    socket: UdpSocket,
-    peer_addr: SocketAddr,
+	socket: UdpSocket,
+	peer_addr: SocketAddr,
 }
 
 impl CoAPClient {
@@ -60,7 +60,7 @@ impl CoAPClient {
 
 				let mut token: Vec<u8> = vec!(1, 1, 1, 1);
 				for x in token.iter_mut() {
-				    *x = random()
+					*x = random()
 				}
 				packet.set_token(token.clone());
 
@@ -81,15 +81,15 @@ impl CoAPClient {
 
 				try!(client.set_receive_timeout(timeout));
 				match client.receive() {
-				 	Ok(receive_packet) => {
-				 		if receive_packet.header.get_message_id() == message_id
-				 			&& *receive_packet.get_token() == token {
-				 				return Ok(receive_packet)
-				 			} else {
-				 				return Err(Error::new(ErrorKind::Other, "receive invalid data"))
-				 			}
-				 	},
-				 	Err(e) => Err(e)
+					Ok(receive_packet) => {
+						if receive_packet.header.get_message_id() == message_id
+							&& *receive_packet.get_token() == token {
+								return Ok(receive_packet)
+							} else {
+								return Err(Error::new(ErrorKind::Other, "receive invalid data"))
+							}
+					},
+					Err(e) => Err(e)
 				}
 			},
 			Err(_) => Err(Error::new(ErrorKind::InvalidInput, "url error"))
@@ -129,7 +129,7 @@ impl CoAPClient {
 
 	/// Set the receive timeout.
 	pub fn set_receive_timeout(&self, dur: Option<Duration>) -> Result<()> {
-	    self.socket.set_read_timeout(dur)
+		self.socket.set_read_timeout(dur)
 	}
 
 	fn coap_scheme_type_mapper(scheme: &str) -> SchemeType {
@@ -156,7 +156,7 @@ mod test {
 		assert!(CoAPClient::request("127.0.0.1").is_err());
 	}
 
-	fn request_handler(_: Packet) -> Option<Packet> {
+	fn request_handler(_: Packet, _:Option<Packet>) -> Option<Packet> {
 		None
 	}
 
diff --git a/src/lib.rs b/src/lib.rs
index 079d5e3..6d7483e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -29,7 +29,7 @@
 //! use coap::packet::*;
 //! use coap::{CoAPServer, CoAPClient};
 
-//! fn request_handler(req: Packet) -> Option<Packet> {
+//! fn request_handler(req: Packet, resp: Option<Packet>) -> Option<Packet> {
 //! 	println!("Receive request: {:?}", req);
 //!     None
 //! }
diff --git a/src/packet.rs b/src/packet.rs
index 3fe80a2..103a54e 100644
--- a/src/packet.rs
+++ b/src/packet.rs
@@ -1,28 +1,27 @@
 use bincode;
 use std::collections::BTreeMap;
 use std::collections::LinkedList;
-use std;
 
 macro_rules! u8_to_unsigned_be {
-    ($src:ident, $start:expr, $end:expr, $t:ty) => ({
-        (0 .. $end - $start + 1).rev().fold(0, |acc, i| acc | $src[$start+i] as $t << i * 8)
-    })
+	($src:ident, $start:expr, $end:expr, $t:ty) => ({
+		(0 .. $end - $start + 1).rev().fold(0, |acc, i| acc | $src[$start+i] as $t << i * 8)
+	})
 }
 
 #[derive(PartialEq, Eq, Debug)]
 pub enum PacketType {
-    Confirmable,
-    NonConfirmable,
-    Acknowledgement,
-    Reset,
-    Invalid,
+	Confirmable,
+	NonConfirmable,
+	Acknowledgement,
+	Reset,
+	Invalid,
 }
 
 #[derive(Default, Debug, RustcEncodable, RustcDecodable)]
 pub struct PacketHeader {
-    ver_type_tkl: u8,
-    code: u8,
-    message_id: u16
+	ver_type_tkl: u8,
+	code: u8,
+	message_id: u16
 }
 
 impl PacketHeader {
@@ -109,9 +108,9 @@ impl PacketHeader {
 #[derive(Debug)]
 pub enum ParseError {
 	InvalidHeader,
-    InvalidTokenLength,
-    InvalidOptionDelta,
-    InvalidOptionLength,
+	InvalidTokenLength,
+	InvalidOptionDelta,
+	InvalidOptionLength,
 }
 
 #[derive(Debug)]
@@ -122,32 +121,32 @@ pub enum PackageError {
 
 #[derive(PartialEq, Eq, Debug)]
 pub enum OptionType {
-    IfMatch,
-    UriHost,
-    ETag,
-    IfNoneMatch,
-    Observe,
-    UriPort,
-    LocationPath,
-    UriPath,
-    ContentFormat,
-    MaxAge,
-    UriQuery,
-    Accept,
-    LocationQuery,
-    Block2,
-    Block1,
-    ProxyUri,
-    ProxyScheme,
-    Size1
+	IfMatch,
+	UriHost,
+	ETag,
+	IfNoneMatch,
+	Observe,
+	UriPort,
+	LocationPath,
+	UriPath,
+	ContentFormat,
+	MaxAge,
+	UriQuery,
+	Accept,
+	LocationQuery,
+	Block2,
+	Block1,
+	ProxyUri,
+	ProxyScheme,
+	Size1
 }
 
 #[derive(Debug)]
 pub struct Packet {
-    pub header: PacketHeader,
-    token: Vec<u8>,
-    options: BTreeMap<usize, LinkedList<Vec<u8>>>,
-    pub payload: Vec<u8>,
+	pub header: PacketHeader,
+	token: Vec<u8>,
+	options: BTreeMap<usize, LinkedList<Vec<u8>>>,
+	pub payload: Vec<u8>,
 }
 
 impl Packet {
@@ -363,14 +362,14 @@ impl Packet {
 				options_delta_length += delta;
 
 				options_bytes.reserve(header.len() + value.len());
-		        unsafe {
-		        	use std::ptr;
-		            let buf_len = options_bytes.len();
-		            ptr::copy(header.as_ptr(), options_bytes.as_mut_ptr().offset(buf_len as isize), header.len());
-		            ptr::copy(value.as_ptr(), options_bytes.as_mut_ptr().offset((buf_len + header.len()) as isize), value.len());
-		            options_bytes.set_len(buf_len + header.len() + value.len());
-		        }
-		    }
+				unsafe {
+					use std::ptr;
+					let buf_len = options_bytes.len();
+					ptr::copy(header.as_ptr(), options_bytes.as_mut_ptr().offset(buf_len as isize), header.len());
+					ptr::copy(value.as_ptr(), options_bytes.as_mut_ptr().offset((buf_len + header.len()) as isize), value.len());
+					options_bytes.set_len(buf_len + header.len() + value.len());
+				}
+			}
 		}
 
 		let mut buf_length = 4 + self.payload.len() + self.token.len();
@@ -388,23 +387,23 @@ impl Packet {
 		match header_result {
 			Ok(_) => {
 				buf.reserve(self.token.len() + options_bytes.len());
-		        unsafe {
-		        	use std::ptr;
-		            let buf_len = buf.len();
-		            ptr::copy(self.token.as_ptr(), buf.as_mut_ptr().offset(buf_len as isize), self.token.len());
-		            ptr::copy(options_bytes.as_ptr(), buf.as_mut_ptr().offset((buf_len + self.token.len()) as isize), options_bytes.len());
-		            buf.set_len(buf_len + self.token.len() + options_bytes.len());
-		        }
+				unsafe {
+					use std::ptr;
+					let buf_len = buf.len();
+					ptr::copy(self.token.as_ptr(), buf.as_mut_ptr().offset(buf_len as isize), self.token.len());
+					ptr::copy(options_bytes.as_ptr(), buf.as_mut_ptr().offset((buf_len + self.token.len()) as isize), options_bytes.len());
+					buf.set_len(buf_len + self.token.len() + options_bytes.len());
+				}
 
 				if self.header.get_code() != "0.00" && self.payload.len() != 0 {
 					buf.push(0xFF);
 					buf.reserve(self.payload.len());
-			        unsafe {
-			        	use std::ptr;
-			            let buf_len = buf.len();
-			            ptr::copy(self.payload.as_ptr(), buf.as_mut_ptr().offset(buf.len() as isize), self.payload.len());
-			            buf.set_len(buf_len + self.payload.len());
-			        }
+					unsafe {
+						use std::ptr;
+						let buf_len = buf.len();
+						ptr::copy(self.payload.as_ptr(), buf.as_mut_ptr().offset(buf.len() as isize), self.payload.len());
+						buf.set_len(buf_len + self.payload.len());
+					}
 				}
 				Ok(buf)
 			},
@@ -437,23 +436,23 @@ impl Packet {
 }
 
 /// Convert a request to a response
-pub fn auto_response(request_packet: Packet) -> std::io::Result<Packet> {
+pub fn auto_response(request_packet: &Packet) -> Option<Packet> {
 		let mut packet = Packet::new();
 
 		packet.header.set_version(1);
 		let response_type = match request_packet.header.get_type() {
 			PacketType::Confirmable => PacketType::Acknowledgement,
 			PacketType::NonConfirmable => PacketType::NonConfirmable,
-			_ => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "request type error"))
+			_ => return None
 		};
 		packet.header.set_type(response_type);
 		packet.header.set_code("2.05");
 		packet.header.set_message_id(request_packet.header.get_message_id());
 		packet.set_token(request_packet.get_token().clone());
 
-		packet.payload = request_packet.payload;
+		packet.payload = request_packet.payload.clone();
 
-		Ok(packet)
+		Some(packet)
 	}
 
 #[cfg(test)]
diff --git a/src/server.rs b/src/server.rs
index 280fcae..f71c211 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -5,7 +5,7 @@ use std::net::{ToSocketAddrs, SocketAddr};
 use std::sync::mpsc;
 use mio::{EventLoop, PollOpt, EventSet, Handler, Sender, Token};
 use mio::udp::UdpSocket;
-use packet::Packet;
+use packet::{Packet, auto_response};
 use threadpool::ThreadPool;
 
 const DEFAULT_WORKER_NUM: usize = 4;
@@ -26,12 +26,12 @@ pub struct CoAPResponse {
 }
 
 pub trait CoAPHandler: Sync + Send + Copy {
-	fn handle(&self, Packet) -> Option<Packet>;
+	fn handle(&self, Packet, Option<Packet>) -> Option<Packet>;
 }
 
-impl<F> CoAPHandler for F where F: Fn(Packet) -> Option<Packet>, F: Sync + Send + Copy {
-	fn handle(&self, request: Packet) -> Option<Packet> {
-		return self(request);
+impl<F> CoAPHandler for F where F: Fn(Packet, Option<Packet>) -> Option<Packet>, F: Sync + Send + Copy {
+	fn handle(&self, request: Packet, response: Option<Packet>) -> Option<Packet> {
+		return self(request, response);
 	}
 }
 
@@ -71,12 +71,13 @@ impl<H: CoAPHandler + 'static> Handler for UdpHandler<H> {
 				debug!("Handling request from {}", src);
 				let response_q = self.tx_sender.clone();
 				self.thread_pool.execute(move || {
-
 					match Packet::from_bytes(&buf[..nread]) {
 						Ok(packet) => {
+							// Pre-generate a response
+							let auto_resp = auto_response(&packet);
 							// Dispatch user handler, if there is a response packet
 							//   send the reply via the TX thread
-							match coap_handler.handle(packet) {
+							match coap_handler.handle(packet, auto_resp) {
 								Some(response) => {
 									debug!("Response: {:?}", response);
 									response_q.send(CoAPResponse{
@@ -94,8 +95,6 @@ impl<H: CoAPHandler + 'static> Handler for UdpHandler<H> {
 							return;
 						}
 					};
-
-
 				});
 			},
 			_ => {
@@ -108,16 +107,16 @@ impl<H: CoAPHandler + 'static> Handler for UdpHandler<H> {
 
 	fn notify(&mut self, event_loop: &mut EventLoop<UdpHandler<H>>, _: ()) {
 		info!("Shutting down request handler");
-        event_loop.shutdown();
-    }
+		event_loop.shutdown();
+	}
 }
 
 pub struct CoAPServer {
-    socket: UdpSocket,
-    event_sender: Option<Sender<()>>,
-    event_thread: Option<thread::JoinHandle<()>>,
-    tx_thread: Option<thread::JoinHandle<()>>,
-    worker_num: usize,
+	socket: UdpSocket,
+	event_sender: Option<Sender<()>>,
+	event_thread: Option<thread::JoinHandle<()>>,
+	tx_thread: Option<thread::JoinHandle<()>>,
+	worker_num: usize,
 }
 
 impl CoAPServer {
@@ -237,29 +236,29 @@ fn transmit_handler(tx_recv: RxQueue, tx_only: UdpSocket) {
 }
 
 impl Drop for CoAPServer {
-    fn drop(&mut self) {
-        self.stop();
-    }
+	fn drop(&mut self) {
+		self.stop();
+	}
 }
 
 
 #[cfg(test)]
 mod test {
 	use super::*;
-	use packet::{Packet, PacketType, OptionType, auto_response};
+	use packet::{Packet, PacketType, OptionType};
 	use client::CoAPClient;
 
-	fn request_handler(req: Packet) -> Option<Packet> {
+	fn request_handler(req: Packet, response: Option<Packet>) -> Option<Packet> {
 		let uri_path_list = req.get_option(OptionType::UriPath).unwrap();
 		assert!(uri_path_list.len() == 1);
 
-		return match auto_response(req) {
-			Ok(mut response) => {
-				response.set_payload(uri_path_list.front().unwrap().clone());
-				Some(response)
+		match response {
+			Some(mut packet) => {
+				packet.set_payload(uri_path_list.front().unwrap().clone());
+				Some(packet)
 			},
-			Err(_) => None
-		};
+			_ => None
+		}
 	}
 
 	#[test]
-- 
GitLab