Эх сурвалжийг харах

Get rid of Result<_, ()>.

The use of this type has several drawbacks:
  * It does not allow distinguishing between different error
    conditions. In fact, we wrongly conflated some of them
    before this commit.
  * It does not allow propagation via ? and requires manual use
    of map_err, which is especially tiresome for downstream code.
  * It prevents us from expanding the set of error conditions
    even if right now we have only one.
  * It prevents us from blanket using Result<T> everywhere
    (a nitpick at most).

Instead, use Result<T, Error> everywhere, and differentiate error
conditions where applicable.
whitequark 7 жил өмнө
parent
commit
5bf64586cd

+ 9 - 9
src/iface/ethernet.rs

@@ -1,6 +1,6 @@
 use managed::{Managed, ManagedSlice};
 
-use Error;
+use {Error, Result};
 use phy::Device;
 use wire::{EthernetAddress, EthernetProtocol, EthernetFrame};
 use wire::{ArpPacket, ArpRepr, ArpOperation};
@@ -109,7 +109,7 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
     /// handling the given set of sockets.
     ///
     /// The timestamp is a monotonically increasing number of milliseconds.
-    pub fn poll(&mut self, sockets: &mut SocketSet, timestamp: u64) -> Result<(), Error> {
+    pub fn poll(&mut self, sockets: &mut SocketSet, timestamp: u64) -> Result<()> {
         // First, transmit any outgoing packets.
         loop {
             if self.emit(sockets, timestamp)? { break }
@@ -140,7 +140,7 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
     // Snoop all ARP traffic, and respond to ARP packets directed at us.
     fn process_arp<'frame, T: AsRef<[u8]>>
                   (&mut self, eth_frame: &EthernetFrame<&'frame T>) ->
-                  Result<Response<'frame>, Error> {
+                  Result<Response<'frame>> {
         let arp_packet = ArpPacket::new_checked(eth_frame.payload())?;
         let arp_repr = ArpRepr::parse(&arp_packet)?;
 
@@ -189,7 +189,7 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
     fn process_ipv4<'frame, T: AsRef<[u8]>>
                    (&mut self, sockets: &mut SocketSet, timestamp: u64,
                     eth_frame: &EthernetFrame<&'frame T>) ->
-                   Result<Response<'frame>, Error> {
+                   Result<Response<'frame>> {
         let ipv4_packet = Ipv4Packet::new_checked(eth_frame.payload())?;
         let ipv4_repr = Ipv4Repr::parse(&ipv4_packet)?;
 
@@ -251,7 +251,7 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
     }
 
     fn process_icmpv4<'frame>(ipv4_repr: Ipv4Repr, ip_payload: &'frame [u8]) ->
-                             Result<Response<'frame>, Error> {
+                             Result<Response<'frame>> {
         let icmp_packet = Icmpv4Packet::new_checked(ip_payload)?;
         let icmp_repr = Icmpv4Repr::parse(&icmp_packet)?;
 
@@ -284,7 +284,7 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
 
     fn process_udpv4<'frame>(sockets: &mut SocketSet, timestamp: u64,
                              ipv4_repr: Ipv4Repr, ip_payload: &'frame [u8]) ->
-                            Result<Response<'frame>, Error> {
+                            Result<Response<'frame>> {
         let ip_repr = IpRepr::Ipv4(ipv4_repr);
 
         for udp_socket in sockets.iter_mut().filter_map(
@@ -316,7 +316,7 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
 
     fn process_tcpv4<'frame>(sockets: &mut SocketSet, timestamp: u64,
                              ipv4_repr: Ipv4Repr, ip_payload: &'frame [u8]) ->
-                            Result<Response<'frame>, Error> {
+                            Result<Response<'frame>> {
         let ip_repr = IpRepr::Ipv4(ipv4_repr);
 
         for tcp_socket in sockets.iter_mut().filter_map(
@@ -359,7 +359,7 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
         Ok(Response::Tcpv4(ipv4_reply_repr, tcp_reply_repr))
     }
 
-    fn send_response(&mut self, timestamp: u64, response: Response) -> Result<(), Error> {
+    fn send_response(&mut self, timestamp: u64, response: Response) -> Result<()> {
         macro_rules! ip_response {
             ($tx_buffer:ident, $frame:ident, $ip_repr:ident) => ({
                 let dst_hardware_addr =
@@ -428,7 +428,7 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
         }
     }
 
-    fn emit(&mut self, sockets: &mut SocketSet, timestamp: u64) -> Result<bool, Error> {
+    fn emit(&mut self, sockets: &mut SocketSet, timestamp: u64) -> Result<bool> {
         // Borrow checker is being overly careful around closures, so we have
         // to hack around that.
         let src_hardware_addr = self.hardware_addr;

+ 3 - 0
src/lib.rs

@@ -134,6 +134,9 @@ pub enum Error {
     __Nonexhaustive
 }
 
+/// The result type for the networking stack.
+pub type Result<T> = core::result::Result<T, Error>;
+
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {

+ 3 - 3
src/phy/fault_injector.rs

@@ -1,4 +1,4 @@
-use Error;
+use {Error, Result};
 use super::{DeviceLimits, Device};
 
 // We use our own RNG to stay compatible with #![no_std].
@@ -196,7 +196,7 @@ impl<D: Device> Device for FaultInjector<D>
         limits
     }
 
-    fn receive(&mut self, timestamp: u64) -> Result<Self::RxBuffer, Error> {
+    fn receive(&mut self, timestamp: u64) -> Result<Self::RxBuffer> {
         let mut buffer = self.inner.receive(timestamp)?;
         if self.state.maybe(self.config.drop_pct) {
             net_trace!("rx: randomly dropping a packet");
@@ -217,7 +217,7 @@ impl<D: Device> Device for FaultInjector<D>
         Ok(buffer)
     }
 
-    fn transmit(&mut self, timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
+    fn transmit(&mut self, timestamp: u64, length: usize) -> Result<Self::TxBuffer> {
         let buffer;
         if self.state.maybe(self.config.drop_pct) {
             net_trace!("tx: randomly dropping a packet");

+ 3 - 3
src/phy/loopback.rs

@@ -11,7 +11,7 @@ use std::collections::VecDeque;
 #[cfg(feature = "collections")]
 use collections::{Vec, VecDeque};
 
-use Error;
+use {Error, Result};
 use super::{Device, DeviceLimits};
 
 /// A loopback device.
@@ -39,14 +39,14 @@ impl Device for Loopback {
         }
     }
 
-    fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> {
+    fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer> {
         match self.0.borrow_mut().pop_front() {
             Some(packet) => Ok(packet),
             None => Err(Error::Exhausted)
         }
     }
 
-    fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
+    fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer> {
         let mut buffer = Vec::new();
         buffer.resize(length, 0);
         Ok(TxBuffer {

+ 6 - 6
src/phy/mod.rs

@@ -20,7 +20,7 @@
 /*!
 ```rust
 use std::slice;
-use smoltcp::Error;
+use smoltcp::{Error, Result};
 use smoltcp::phy::{DeviceLimits, Device};
 
 const TX_BUFFERS: [*mut u8; 2] = [0x10000000 as *mut u8, 0x10001000 as *mut u8];
@@ -61,7 +61,7 @@ impl Device for EthernetDevice {
         limits
     }
 
-    fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> {
+    fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer> {
         if rx_full() {
             let index = self.rx_next;
             self.rx_next = (self.rx_next + 1) % RX_BUFFERS.len();
@@ -75,7 +75,7 @@ impl Device for EthernetDevice {
         }
     }
 
-    fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
+    fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer> {
         if tx_empty() {
             let index = self.tx_next;
             self.tx_next = (self.tx_next + 1) % TX_BUFFERS.len();
@@ -104,7 +104,7 @@ impl Drop for EthernetTxBuffer {
 ```
 */
 
-use Error;
+use {Error, Result};
 
 #[cfg(any(feature = "raw_socket", feature = "tap_interface"))]
 mod sys;
@@ -177,12 +177,12 @@ pub trait Device {
     /// It is expected that a `receive` implementation, once a packet is written to memory
     /// through DMA, would gain ownership of the underlying buffer, provide it for parsing,
     /// and return it to the network device once it is dropped.
-    fn receive(&mut self, timestamp: u64) -> Result<Self::RxBuffer, Error>;
+    fn receive(&mut self, timestamp: u64) -> Result<Self::RxBuffer>;
 
     /// Transmit a frame.
     ///
     /// It is expected that a `transmit` implementation would gain ownership of a buffer with
     /// the requested length, provide it for emission, and schedule it to be read from
     /// memory by the network device once it is dropped.
-    fn transmit(&mut self, timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error>;
+    fn transmit(&mut self, timestamp: u64, length: usize) -> Result<Self::TxBuffer>;
 }

+ 3 - 3
src/phy/pcap_writer.rs

@@ -3,7 +3,7 @@ use core::cell::RefCell;
 use std::io::Write;
 use byteorder::{ByteOrder, NativeEndian};
 
-use Error;
+use {Error, Result};
 use super::{DeviceLimits, Device};
 
 enum_with_unknown! {
@@ -136,7 +136,7 @@ impl<D: Device, S: PcapSink + Clone> Device for PcapWriter<D, S> {
 
     fn limits(&self) -> DeviceLimits { self.lower.limits() }
 
-    fn receive(&mut self, timestamp: u64) -> Result<Self::RxBuffer, Error> {
+    fn receive(&mut self, timestamp: u64) -> Result<Self::RxBuffer> {
         let buffer = self.lower.receive(timestamp)?;
         match self.mode {
             PcapMode::Both | PcapMode::RxOnly =>
@@ -146,7 +146,7 @@ impl<D: Device, S: PcapSink + Clone> Device for PcapWriter<D, S> {
         Ok(buffer)
     }
 
-    fn transmit(&mut self, timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
+    fn transmit(&mut self, timestamp: u64, length: usize) -> Result<Self::TxBuffer> {
         let buffer = self.lower.transmit(timestamp, length)?;
         Ok(TxBuffer { buffer, timestamp, sink: self.sink.clone(), mode: self.mode })
     }

+ 3 - 3
src/phy/raw_socket.rs

@@ -3,7 +3,7 @@ use std::vec::Vec;
 use std::rc::Rc;
 use std::io;
 
-use Error;
+use {Error, Result};
 use super::{sys, DeviceLimits, Device};
 
 /// A socket that captures or transmits the complete frame.
@@ -40,7 +40,7 @@ impl Device for RawSocket {
         }
     }
 
-    fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> {
+    fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer> {
         let mut lower = self.lower.borrow_mut();
         let mut buffer = vec![0; self.mtu];
         let size = lower.recv(&mut buffer[..]).unwrap();
@@ -48,7 +48,7 @@ impl Device for RawSocket {
         Ok(buffer)
     }
 
-    fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
+    fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer> {
         Ok(TxBuffer {
             lower:  self.lower.clone(),
             buffer: vec![0; length]

+ 3 - 3
src/phy/tap_interface.rs

@@ -3,7 +3,7 @@ use std::vec::Vec;
 use std::rc::Rc;
 use std::io;
 
-use Error;
+use {Error, Result};
 use super::{sys, DeviceLimits, Device};
 
 /// A virtual Ethernet interface.
@@ -41,7 +41,7 @@ impl Device for TapInterface {
         }
     }
 
-    fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> {
+    fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer> {
         let mut lower = self.lower.borrow_mut();
         let mut buffer = vec![0; self.mtu];
         match lower.recv(&mut buffer[..]) {
@@ -56,7 +56,7 @@ impl Device for TapInterface {
         }
     }
 
-    fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
+    fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer> {
         Ok(TxBuffer {
             lower:  self.lower.clone(),
             buffer: vec![0; length]

+ 3 - 3
src/phy/tracer.rs

@@ -1,4 +1,4 @@
-use Error;
+use {Error, Result};
 use wire::pretty_print::{PrettyPrint, PrettyPrinter};
 use super::{DeviceLimits, Device};
 
@@ -33,13 +33,13 @@ impl<D: Device, P: PrettyPrint> Device for Tracer<D, P> {
 
     fn limits(&self) -> DeviceLimits { self.inner.limits() }
 
-    fn receive(&mut self, timestamp: u64) -> Result<Self::RxBuffer, Error> {
+    fn receive(&mut self, timestamp: u64) -> Result<Self::RxBuffer> {
         let buffer = self.inner.receive(timestamp)?;
         (self.writer)(timestamp, PrettyPrinter::<P>::new("<- ", &buffer));
         Ok(buffer)
     }
 
-    fn transmit(&mut self, timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
+    fn transmit(&mut self, timestamp: u64, length: usize) -> Result<Self::TxBuffer> {
         let buffer = self.inner.transmit(timestamp, length)?;
         Ok(TxBuffer { buffer, timestamp, writer: self.writer })
     }

+ 3 - 3
src/socket/mod.rs

@@ -10,7 +10,7 @@
 //! The interface implemented by this module uses explicit buffering: you decide on the good
 //! size for a buffer, allocate it, and let the networking stack use it.
 
-use Error;
+use {Error, Result};
 use phy::DeviceLimits;
 use wire::IpRepr;
 
@@ -82,8 +82,8 @@ impl<'a, 'b> Socket<'a, 'b> {
     }
 
     pub(crate) fn dispatch<F, R>(&mut self, timestamp: u64, limits: &DeviceLimits,
-                                 emit: &mut F) -> Result<R, Error>
-            where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
+                                 emit: &mut F) -> Result<R>
+            where F: FnMut(&IpRepr, &IpPayload) -> Result<R> {
         dispatch_socket!(self, |socket [mut]| socket.dispatch(timestamp, limits, emit))
     }
 }

+ 13 - 13
src/socket/raw.rs

@@ -1,6 +1,6 @@
 use managed::Managed;
 
-use Error;
+use {Error, Result};
 use phy::DeviceLimits;
 use wire::{IpVersion, IpProtocol, Ipv4Repr, Ipv4Packet};
 use socket::{IpRepr, IpPayload, Socket};
@@ -109,9 +109,9 @@ impl<'a, 'b> RawSocket<'a, 'b> {
 
     /// Enqueue a packet to send, and return a pointer to its payload.
     ///
-    /// This function returns `Err(())` if the size is greater than what
-    /// the transmit buffer can accomodate.
-    pub fn send(&mut self, size: usize) -> Result<&mut [u8], ()> {
+    /// This function returns `Err(Error::Exhausted)` if the size is greater than
+    /// the transmit packet buffer size.
+    pub fn send(&mut self, size: usize) -> Result<&mut [u8]> {
         let packet_buf = self.tx_buffer.enqueue()?;
         packet_buf.size = size;
         net_trace!("[{}]:{}:{}: buffer to send {} octets",
@@ -123,7 +123,7 @@ impl<'a, 'b> RawSocket<'a, 'b> {
     /// Enqueue a packet to send, and fill it from a slice.
     ///
     /// See also [send](#method.send).
-    pub fn send_slice(&mut self, data: &[u8]) -> Result<usize, ()> {
+    pub fn send_slice(&mut self, data: &[u8]) -> Result<usize> {
         let buffer = self.send(data.len())?;
         let data = &data[..buffer.len()];
         buffer.copy_from_slice(data);
@@ -132,8 +132,8 @@ impl<'a, 'b> RawSocket<'a, 'b> {
 
     /// Dequeue a packet, and return a pointer to the payload.
     ///
-    /// This function returns `Err(())` if the receive buffer is empty.
-    pub fn recv(&mut self) -> Result<&[u8], ()> {
+    /// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
+    pub fn recv(&mut self) -> Result<&[u8]> {
         let packet_buf = self.rx_buffer.dequeue()?;
         net_trace!("[{}]:{}:{}: receive {} buffered octets",
                    self.debug_id, self.ip_version, self.ip_protocol,
@@ -144,21 +144,21 @@ impl<'a, 'b> RawSocket<'a, 'b> {
     /// Dequeue a packet, and copy the payload into the given slice.
     ///
     /// See also [recv](#method.recv).
-    pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<usize, ()> {
+    pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<usize> {
         let buffer = self.recv()?;
         data[..buffer.len()].copy_from_slice(buffer);
         Ok(buffer.len())
     }
 
     pub(crate) fn process(&mut self, _timestamp: u64, ip_repr: &IpRepr,
-                          payload: &[u8]) -> Result<(), Error> {
+                          payload: &[u8]) -> Result<()> {
         match self.ip_version {
             IpVersion::Ipv4 => {
                 if ip_repr.protocol() != self.ip_protocol {
                     return Err(Error::Rejected);
                 }
                 let header_len = ip_repr.buffer_len();
-                let packet_buf = self.rx_buffer.enqueue().map_err(|()| Error::Exhausted)?;
+                let packet_buf = self.rx_buffer.enqueue()?;
                 packet_buf.size = header_len + payload.len();
                 ip_repr.emit(&mut packet_buf.as_mut()[..header_len]);
                 packet_buf.as_mut()[header_len..header_len + payload.len()]
@@ -174,9 +174,9 @@ impl<'a, 'b> RawSocket<'a, 'b> {
 
     /// See [Socket::dispatch](enum.Socket.html#method.dispatch).
     pub(crate) fn dispatch<F, R>(&mut self, _timestamp: u64, _limits: &DeviceLimits,
-                                 emit: &mut F) -> Result<R, Error>
-            where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
-        let mut packet_buf = self.tx_buffer.dequeue().map_err(|()| Error::Exhausted)?;
+                                 emit: &mut F) -> Result<R>
+            where F: FnMut(&IpRepr, &IpPayload) -> Result<R> {
+        let mut packet_buf = self.tx_buffer.dequeue()?;
         net_trace!("[{}]:{}:{}: sending {} octets",
                    self.debug_id, self.ip_version, self.ip_protocol,
                    packet_buf.size);

+ 29 - 19
src/socket/tcp.rs

@@ -4,7 +4,7 @@
 use core::fmt;
 use managed::Managed;
 
-use Error;
+use {Error, Result};
 use phy::DeviceLimits;
 use wire::{IpProtocol, IpAddress, IpEndpoint};
 use wire::{TcpSeqNumber, TcpPacket, TcpRepr, TcpControl};
@@ -350,12 +350,12 @@ impl<'a> TcpSocket<'a> {
     ///
     /// This function returns an error if the socket was open; see [is_open](#method.is_open).
     /// It also returns an error if the specified port is zero.
-    pub fn listen<T>(&mut self, local_endpoint: T) -> Result<(), ()>
+    pub fn listen<T>(&mut self, local_endpoint: T) -> Result<()>
             where T: Into<IpEndpoint> {
         let local_endpoint = local_endpoint.into();
 
-        if self.is_open() { return Err(()) }
-        if local_endpoint.port == 0 { return Err(()) }
+        if self.is_open() { return Err(Error::Illegal) }
+        if local_endpoint.port == 0 { return Err(Error::Unaddressable) }
 
         self.reset();
         self.listen_address  = local_endpoint.addr;
@@ -379,7 +379,7 @@ impl<'a> TcpSocket<'a> {
     /// This function returns an error if the socket was open; see [is_open](#method.is_open).
     /// It also returns an error if the local or remote port is zero, or if the remote address
     /// is unspecified.
-    pub fn connect<T, U>(&mut self, remote_endpoint: T, local_endpoint: U) -> Result<(), Error>
+    pub fn connect<T, U>(&mut self, remote_endpoint: T, local_endpoint: U) -> Result<()>
             where T: Into<IpEndpoint>, U: Into<IpEndpoint> {
         let remote_endpoint = remote_endpoint.into();
         let local_endpoint  = local_endpoint.into();
@@ -565,10 +565,10 @@ impl<'a> TcpSocket<'a> {
     /// there is not enough contiguous free space in the transmit buffer, down to
     /// an empty slice.
     ///
-    /// This function returns an error if the transmit half of the connection is not open;
-    /// see [can_send](#method.can_send).
-    pub fn send(&mut self, size: usize) -> Result<&mut [u8], ()> {
-        if !self.may_send() { return Err(()) }
+    /// This function returns `Err(Error::Illegal) if the transmit half of
+    /// the connection is not open; see [may_send](#method.may_send).
+    pub fn send(&mut self, size: usize) -> Result<&mut [u8]> {
+        if !self.may_send() { return Err(Error::Illegal) }
 
         #[cfg(any(test, feature = "verbose"))]
         let old_length = self.tx_buffer.len();
@@ -589,7 +589,7 @@ impl<'a> TcpSocket<'a> {
     /// by the amount of free space in the transmit buffer; down to zero.
     ///
     /// See also [send](#method.send).
-    pub fn send_slice(&mut self, data: &[u8]) -> Result<usize, ()> {
+    pub fn send_slice(&mut self, data: &[u8]) -> Result<usize> {
         let buffer = self.send(data.len())?;
         let data = &data[..buffer.len()];
         buffer.copy_from_slice(data);
@@ -601,11 +601,14 @@ impl<'a> TcpSocket<'a> {
     /// This function may return a slice smaller than the requested size in case
     /// there are not enough octets queued in the receive buffer, down to
     /// an empty slice.
-    pub fn recv(&mut self, size: usize) -> Result<&[u8], ()> {
+    ///
+    /// This function returns `Err(Error::Illegal) if the receive half of
+    /// the connection is not open; see [may_recv](#method.may_recv).
+    pub fn recv(&mut self, size: usize) -> Result<&[u8]> {
         // We may have received some data inside the initial SYN, but until the connection
         // is fully open we must not dequeue any data, as it may be overwritten by e.g.
         // another (stale) SYN.
-        if !self.may_recv() { return Err(()) }
+        if !self.may_recv() { return Err(Error::Illegal) }
 
         #[cfg(any(test, feature = "verbose"))]
         let old_length = self.rx_buffer.len();
@@ -626,7 +629,7 @@ impl<'a> TcpSocket<'a> {
     /// by the amount of free space in the transmit buffer; down to zero.
     ///
     /// See also [recv](#method.recv).
-    pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<usize, ()> {
+    pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<usize> {
         let buffer = self.recv(data.len())?;
         let data = &mut data[..buffer.len()];
         data.copy_from_slice(buffer);
@@ -649,7 +652,7 @@ impl<'a> TcpSocket<'a> {
     }
 
     pub(crate) fn process(&mut self, timestamp: u64, ip_repr: &IpRepr,
-                          payload: &[u8]) -> Result<(), Error> {
+                          payload: &[u8]) -> Result<()> {
         debug_assert!(ip_repr.protocol() == IpProtocol::Tcp);
 
         if self.state == State::Closed { return Err(Error::Rejected) }
@@ -980,8 +983,8 @@ impl<'a> TcpSocket<'a> {
     }
 
     pub(crate) fn dispatch<F, R>(&mut self, timestamp: u64, limits: &DeviceLimits,
-                                 emit: &mut F) -> Result<R, Error>
-            where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
+                                 emit: &mut F) -> Result<R>
+            where F: FnMut(&IpRepr, &IpPayload) -> Result<R> {
         if !self.remote_endpoint.is_specified() { return Err(Error::Exhausted) }
 
         let mut repr = TcpRepr {
@@ -1266,7 +1269,7 @@ mod test {
         payload: &[]
     };
 
-    fn send(socket: &mut TcpSocket, timestamp: u64, repr: &TcpRepr) -> Result<(), Error> {
+    fn send(socket: &mut TcpSocket, timestamp: u64, repr: &TcpRepr) -> Result<()> {
         trace!("send: {}", repr);
         let mut buffer = vec![0; repr.buffer_len()];
         let mut packet = TcpPacket::new(&mut buffer);
@@ -1281,7 +1284,7 @@ mod test {
     }
 
     fn recv<F>(socket: &mut TcpSocket, timestamp: u64, mut f: F)
-            where F: FnMut(Result<TcpRepr, Error>) {
+            where F: FnMut(Result<TcpRepr>) {
         let mut buffer = vec![];
         let mut limits = DeviceLimits::default();
         limits.max_transmission_unit = 1520;
@@ -1446,7 +1449,14 @@ mod test {
     #[test]
     fn test_listen_validation() {
         let mut s = socket();
-        assert_eq!(s.listen(0), Err(()));
+        assert_eq!(s.listen(0), Err(Error::Unaddressable));
+    }
+
+    #[test]
+    fn test_listen_twice() {
+        let mut s = socket();
+        assert_eq!(s.listen(80), Ok(()));
+        assert_eq!(s.listen(80), Err(Error::Illegal));
     }
 
     #[test]

+ 13 - 13
src/socket/udp.rs

@@ -1,6 +1,6 @@
 use managed::Managed;
 
-use Error;
+use {Error, Result};
 use phy::DeviceLimits;
 use wire::{IpProtocol, IpEndpoint};
 use wire::{UdpPacket, UdpRepr};
@@ -109,9 +109,9 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
     /// Enqueue a packet to be sent to a given remote endpoint, and return a pointer
     /// to its payload.
     ///
-    /// This function returns `Err(())` if the size is greater than what
-    /// the transmit buffer can accomodate.
-    pub fn send(&mut self, size: usize, endpoint: IpEndpoint) -> Result<&mut [u8], ()> {
+    /// This function returns `Err(Error::Exhausted)` if the size is greater than
+    /// the transmit packet buffer size.
+    pub fn send(&mut self, size: usize, endpoint: IpEndpoint) -> Result<&mut [u8]> {
         let packet_buf = self.tx_buffer.enqueue()?;
         packet_buf.endpoint = endpoint;
         packet_buf.size = size;
@@ -124,7 +124,7 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
     /// Enqueue a packet to be sent to a given remote endpoint, and fill it from a slice.
     ///
     /// See also [send](#method.send).
-    pub fn send_slice(&mut self, data: &[u8], endpoint: IpEndpoint) -> Result<usize, ()> {
+    pub fn send_slice(&mut self, data: &[u8], endpoint: IpEndpoint) -> Result<usize> {
         let buffer = self.send(data.len(), endpoint)?;
         let data = &data[..buffer.len()];
         buffer.copy_from_slice(data);
@@ -134,8 +134,8 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
     /// Dequeue a packet received from a remote endpoint, and return the endpoint as well
     /// as a pointer to the payload.
     ///
-    /// This function returns `Err(())` if the receive buffer is empty.
-    pub fn recv(&mut self) -> Result<(&[u8], IpEndpoint), ()> {
+    /// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
+    pub fn recv(&mut self) -> Result<(&[u8], IpEndpoint)> {
         let packet_buf = self.rx_buffer.dequeue()?;
         net_trace!("[{}]{}:{}: receive {} buffered octets",
                    self.debug_id, self.endpoint,
@@ -147,14 +147,14 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
     /// as copy the payload into the given slice.
     ///
     /// See also [recv](#method.recv).
-    pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<(usize, IpEndpoint), ()> {
+    pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<(usize, IpEndpoint)> {
         let (buffer, endpoint) = self.recv()?;
         data[..buffer.len()].copy_from_slice(buffer);
         Ok((buffer.len(), endpoint))
     }
 
     pub(crate) fn process(&mut self, _timestamp: u64, ip_repr: &IpRepr,
-                          payload: &[u8]) -> Result<(), Error> {
+                          payload: &[u8]) -> Result<()> {
         debug_assert!(ip_repr.protocol() == IpProtocol::Udp);
 
         let packet = UdpPacket::new_checked(&payload[..ip_repr.payload_len()])?;
@@ -165,7 +165,7 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
             if self.endpoint.addr != ip_repr.dst_addr() { return Err(Error::Rejected) }
         }
 
-        let packet_buf = self.rx_buffer.enqueue().map_err(|()| Error::Exhausted)?;
+        let packet_buf = self.rx_buffer.enqueue()?;
         packet_buf.endpoint = IpEndpoint { addr: ip_repr.src_addr(), port: repr.src_port };
         packet_buf.size = repr.payload.len();
         packet_buf.as_mut()[..repr.payload.len()].copy_from_slice(repr.payload);
@@ -176,9 +176,9 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
     }
 
     pub(crate) fn dispatch<F, R>(&mut self, _timestamp: u64, _limits: &DeviceLimits,
-                                 emit: &mut F) -> Result<R, Error>
-            where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
-        let packet_buf = self.tx_buffer.dequeue().map_err(|()| Error::Exhausted)?;
+                                 emit: &mut F) -> Result<R>
+            where F: FnMut(&IpRepr, &IpPayload) -> Result<R> {
+        let packet_buf = self.tx_buffer.dequeue()?;
         net_trace!("[{}]{}:{}: sending {} octets",
                    self.debug_id, self.endpoint,
                    packet_buf.endpoint, packet_buf.size);

+ 12 - 10
src/storage/ring_buffer.rs

@@ -1,5 +1,7 @@
 use managed::Managed;
-use storage::Resettable;
+
+use {Error, Result};
+use super::Resettable;
 
 /// A ring buffer.
 #[derive(Debug)]
@@ -47,10 +49,10 @@ impl<'a, T: 'a> RingBuffer<'a, T> {
     }
 
     /// Enqueue an element into the buffer, and return a pointer to it, or return
-    /// `Err(())` if the buffer is full.
-    pub fn enqueue(&mut self) -> Result<&mut T, ()> {
+    /// `Err(Error::Exhausted)` if the buffer is full.
+    pub fn enqueue(&mut self) -> Result<&mut T> {
         if self.full() {
-            Err(())
+            Err(Error::Exhausted)
         } else {
             let index = self.mask(self.read_at + self.length);
             let result = &mut self.storage[index];
@@ -60,10 +62,10 @@ impl<'a, T: 'a> RingBuffer<'a, T> {
     }
 
     /// Dequeue an element from the buffer, and return a mutable reference to it, or return
-    /// `Err(())` if the buffer is empty.
-    pub fn dequeue(&mut self) -> Result<&mut T, ()> {
+    /// `Err(Error::Exhausted)` if the buffer is empty.
+    pub fn dequeue(&mut self) -> Result<&mut T> {
         if self.empty() {
-            Err(())
+            Err(Error::Exhausted)
         } else {
             self.length -= 1;
             let read_at = self.read_at;
@@ -95,7 +97,7 @@ mod test {
         let mut ring_buffer = RingBuffer::new(&mut storage[..]);
         assert!(ring_buffer.empty());
         assert!(!ring_buffer.full());
-        assert_eq!(ring_buffer.dequeue(), Err(()));
+        assert_eq!(ring_buffer.dequeue(), Err(Error::Exhausted));
         ring_buffer.enqueue().unwrap();
         assert!(!ring_buffer.empty());
         assert!(!ring_buffer.full());
@@ -104,13 +106,13 @@ mod test {
             assert!(!ring_buffer.empty());
         }
         assert!(ring_buffer.full());
-        assert_eq!(ring_buffer.enqueue(), Err(()));
+        assert_eq!(ring_buffer.enqueue(), Err(Error::Exhausted));
 
         for i in 0..TEST_BUFFER_SIZE {
             assert_eq!(*ring_buffer.dequeue().unwrap(), i);
             assert!(!ring_buffer.full());
         }
-        assert_eq!(ring_buffer.dequeue(), Err(()));
+        assert_eq!(ring_buffer.dequeue(), Err(Error::Exhausted));
         assert!(ring_buffer.empty());
     }
 }

+ 6 - 5
src/wire/arp.rs

@@ -1,6 +1,7 @@
 use core::fmt;
 use byteorder::{ByteOrder, NetworkEndian};
-use Error;
+
+use {Error, Result};
 
 pub use super::EthernetProtocol as Protocol;
 
@@ -71,7 +72,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     ///
     /// [new]: #method.new
     /// [check_len]: #method.check_len
-    pub fn new_checked(buffer: T) -> Result<Packet<T>, Error> {
+    pub fn new_checked(buffer: T) -> Result<Packet<T>> {
         let packet = Self::new(buffer);
         packet.check_len()?;
         Ok(packet)
@@ -85,7 +86,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     ///
     /// [set_hardware_len]: #method.set_hardware_len
     /// [set_protocol_len]: #method.set_protocol_len
-    pub fn check_len(&self) -> Result<(), Error> {
+    pub fn check_len(&self) -> Result<()> {
         let len = self.buffer.as_ref().len();
         if len < field::OPER.end {
             Err(Error::Truncated)
@@ -260,8 +261,8 @@ pub enum Repr {
 
 impl Repr {
     /// Parse an Address Resolution Protocol packet and return a high-level representation,
-    /// or return `Err(())` if the packet is not recognized.
-    pub fn parse<T: AsRef<[u8]>>(packet: &Packet<T>) -> Result<Repr, Error> {
+    /// or return `Err(Error::Unrecognized)` if the packet is not recognized.
+    pub fn parse<T: AsRef<[u8]>>(packet: &Packet<T>) -> Result<Repr> {
         match (packet.hardware_type(), packet.protocol_type(),
                packet.hardware_len(), packet.protocol_len()) {
             (Hardware::Ethernet, Protocol::Ipv4, 6, 4) => {

+ 3 - 3
src/wire/ethernet.rs

@@ -1,7 +1,7 @@
 use core::fmt;
 use byteorder::{ByteOrder, NetworkEndian};
 
-use Error;
+use {Error, Result};
 
 enum_with_unknown! {
     /// Ethernet protocol type.
@@ -100,7 +100,7 @@ impl<T: AsRef<[u8]>> Frame<T> {
     ///
     /// [new]: #method.new
     /// [check_len]: #method.check_len
-    pub fn new_checked(buffer: T) -> Result<Frame<T>, Error> {
+    pub fn new_checked(buffer: T) -> Result<Frame<T>> {
         let packet = Self::new(buffer);
         packet.check_len()?;
         Ok(packet)
@@ -108,7 +108,7 @@ impl<T: AsRef<[u8]>> Frame<T> {
 
     /// Ensure that no accessor method will panic if called.
     /// Returns `Err(Error::Truncated)` if the buffer is too short.
-    pub fn check_len(&self) -> Result<(), Error> {
+    pub fn check_len(&self) -> Result<()> {
         let len = self.buffer.as_ref().len();
         if len < field::PAYLOAD.start {
             Err(Error::Truncated)

+ 4 - 4
src/wire/icmpv4.rs

@@ -1,7 +1,7 @@
 use core::{cmp, fmt};
 use byteorder::{ByteOrder, NetworkEndian};
 
-use Error;
+use {Error, Result};
 use super::ip::checksum;
 use super::{Ipv4Packet, Ipv4Repr};
 
@@ -193,7 +193,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     ///
     /// [new]: #method.new
     /// [check_len]: #method.check_len
-    pub fn new_checked(buffer: T) -> Result<Packet<T>, Error> {
+    pub fn new_checked(buffer: T) -> Result<Packet<T>> {
         let packet = Self::new(buffer);
         packet.check_len()?;
         Ok(packet)
@@ -205,7 +205,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     /// The result of this check is invalidated by calling [set_header_len].
     ///
     /// [set_header_len]: #method.set_header_len
-    pub fn check_len(&self) -> Result<(), Error> {
+    pub fn check_len(&self) -> Result<()> {
         let len = self.buffer.as_ref().len();
         if len < field::CHECKSUM.end {
             Err(Error::Truncated)
@@ -384,7 +384,7 @@ pub enum Repr<'a> {
 impl<'a> Repr<'a> {
     /// Parse an Internet Control Message Protocol version 4 packet and return
     /// a high-level representation.
-    pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&'a T>) -> Result<Repr<'a>, Error> {
+    pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&'a T>) -> Result<Repr<'a>> {
         match (packet.msg_type(), packet.msg_code()) {
             (Message::EchoRequest, 0) => {
                 Ok(Repr::EchoRequest {

+ 2 - 2
src/wire/ip.rs

@@ -1,6 +1,6 @@
 use core::fmt;
 
-use Error;
+use {Error, Result};
 use super::{Ipv4Address, Ipv4Packet, Ipv4Repr};
 
 /// Internet protocol version.
@@ -205,7 +205,7 @@ impl IpRepr {
     /// # Panics
     /// This function panics if source and destination addresses belong to different families,
     /// or the destination address is unspecified, since this indicates a logic error.
-    pub fn lower(&self, fallback_src_addrs: &[Address]) -> Result<IpRepr, Error> {
+    pub fn lower(&self, fallback_src_addrs: &[Address]) -> Result<IpRepr> {
         match self {
             &IpRepr::Unspecified {
                 src_addr: Address::Ipv4(src_addr),

+ 4 - 4
src/wire/ipv4.rs

@@ -1,7 +1,7 @@
 use core::fmt;
 use byteorder::{ByteOrder, NetworkEndian};
 
-use Error;
+use {Error, Result};
 use super::ip::checksum;
 use super::IpAddress;
 
@@ -106,7 +106,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     ///
     /// [new]: #method.new
     /// [check_len]: #method.check_len
-    pub fn new_checked(buffer: T) -> Result<Packet<T>, Error> {
+    pub fn new_checked(buffer: T) -> Result<Packet<T>> {
         let packet = Self::new(buffer);
         packet.check_len()?;
         Ok(packet)
@@ -118,7 +118,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     /// The result of this check is invalidated by calling [set_header_len].
     ///
     /// [set_header_len]: #method.set_header_len
-    pub fn check_len(&self) -> Result<(), Error> {
+    pub fn check_len(&self) -> Result<()> {
         let len = self.buffer.as_ref().len();
         if len < field::DST_ADDR.end {
             Err(Error::Truncated)
@@ -398,7 +398,7 @@ pub struct Repr {
 
 impl Repr {
     /// Parse an Internet Protocol version 4 packet and return a high-level representation.
-    pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&T>) -> Result<Repr, Error> {
+    pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Packet<&T>) -> Result<Repr> {
         // Version 4 is expected.
         if packet.version() != 4 { return Err(Error::Malformed) }
         // Valid checksum is expected.

+ 5 - 5
src/wire/tcp.rs

@@ -1,7 +1,7 @@
 use core::{i32, ops, cmp, fmt};
 use byteorder::{ByteOrder, NetworkEndian};
 
-use Error;
+use {Error, Result};
 use super::{IpProtocol, IpAddress};
 use super::ip::checksum;
 
@@ -110,7 +110,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     ///
     /// [new]: #method.new
     /// [check_len]: #method.check_len
-    pub fn new_checked(buffer: T) -> Result<Packet<T>, Error> {
+    pub fn new_checked(buffer: T) -> Result<Packet<T>> {
         let packet = Self::new(buffer);
         packet.check_len()?;
         Ok(packet)
@@ -124,7 +124,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     /// The result of this check is invalidated by calling [set_header_len].
     ///
     /// [set_header_len]: #method.set_header_len
-    pub fn check_len(&self) -> Result<(), Error> {
+    pub fn check_len(&self) -> Result<()> {
         let len = self.buffer.as_ref().len();
         if len < field::URGENT.end {
             Err(Error::Truncated)
@@ -519,7 +519,7 @@ pub enum TcpOption<'a> {
 }
 
 impl<'a> TcpOption<'a> {
-    pub fn parse(buffer: &'a [u8]) -> Result<(&'a [u8], TcpOption<'a>), Error> {
+    pub fn parse(buffer: &'a [u8]) -> Result<(&'a [u8], TcpOption<'a>)> {
         let (length, option);
         match *buffer.get(0).ok_or(Error::Truncated)? {
             field::OPT_END => {
@@ -627,7 +627,7 @@ impl<'a> Repr<'a> {
     /// Parse a Transmission Control Protocol packet and return a high-level representation.
     pub fn parse<T: ?Sized>(packet: &Packet<&'a T>,
                             src_addr: &IpAddress,
-                            dst_addr: &IpAddress) -> Result<Repr<'a>, Error>
+                            dst_addr: &IpAddress) -> Result<Repr<'a>>
             where T: AsRef<[u8]> {
         // Source and destination ports must be present.
         if packet.src_port() == 0 { return Err(Error::Malformed) }

+ 4 - 4
src/wire/udp.rs

@@ -1,7 +1,7 @@
 use core::fmt;
 use byteorder::{ByteOrder, NetworkEndian};
 
-use Error;
+use {Error, Result};
 use super::{IpProtocol, IpAddress};
 use super::ip::checksum;
 
@@ -36,7 +36,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     ///
     /// [new]: #method.new
     /// [check_len]: #method.check_len
-    pub fn new_checked(buffer: T) -> Result<Packet<T>, Error> {
+    pub fn new_checked(buffer: T) -> Result<Packet<T>> {
         let packet = Self::new(buffer);
         packet.check_len()?;
         Ok(packet)
@@ -50,7 +50,7 @@ impl<T: AsRef<[u8]>> Packet<T> {
     /// The result of this check is invalidated by calling [set_len].
     ///
     /// [set_len]: #method.set_len
-    pub fn check_len(&self) -> Result<(), Error> {
+    pub fn check_len(&self) -> Result<()> {
         let buffer_len = self.buffer.as_ref().len();
         if buffer_len < field::CHECKSUM.end {
             Err(Error::Truncated)
@@ -203,7 +203,7 @@ impl<'a> Repr<'a> {
     /// Parse an User Datagram Protocol packet and return a high-level representation.
     pub fn parse<T: ?Sized>(packet: &Packet<&'a T>,
                             src_addr: &IpAddress,
-                            dst_addr: &IpAddress) -> Result<Repr<'a>, Error>
+                            dst_addr: &IpAddress) -> Result<Repr<'a>>
             where T: AsRef<[u8]> {
         // Destination port cannot be omitted (but source port can be).
         if packet.dst_port() == 0 { return Err(Error::Malformed) }