| // Not all functions are used by all tests. |
| #![allow(dead_code)] |
| |
| use std::io::{self, Read, Write}; |
| use std::net::SocketAddr; |
| use std::sync::Once; |
| use std::time::Duration; |
| |
| use bytes::{Buf, BufMut}; |
| use mio::{Events, Poll}; |
| |
| pub fn init() { |
| static INIT: Once = Once::new(); |
| |
| INIT.call_once(|| { |
| env_logger::try_init().expect("unable to initialise logger"); |
| }) |
| } |
| |
| pub fn assert_sync<T: Sync>() {} |
| pub fn assert_send<T: Send>() {} |
| |
| pub trait TryRead { |
| fn try_read_buf<B: BufMut>(&mut self, buf: &mut B) -> io::Result<Option<usize>> |
| where |
| Self: Sized, |
| { |
| // Reads the length of the slice supplied by buf.mut_bytes into the buffer |
| // This is not guaranteed to consume an entire datagram or segment. |
| // If your protocol is msg based (instead of continuous stream) you should |
| // ensure that your buffer is large enough to hold an entire segment (1532 bytes if not jumbo |
| // frames) |
| let res = self.try_read(unsafe { buf.bytes_mut() }); |
| |
| if let Ok(Some(cnt)) = res { |
| unsafe { |
| buf.advance_mut(cnt); |
| } |
| } |
| |
| res |
| } |
| |
| fn try_read(&mut self, buf: &mut [u8]) -> io::Result<Option<usize>>; |
| } |
| |
| pub trait TryWrite { |
| fn try_write_buf<B: Buf>(&mut self, buf: &mut B) -> io::Result<Option<usize>> |
| where |
| Self: Sized, |
| { |
| let res = self.try_write(buf.bytes()); |
| |
| if let Ok(Some(cnt)) = res { |
| buf.advance(cnt); |
| } |
| |
| res |
| } |
| |
| fn try_write(&mut self, buf: &[u8]) -> io::Result<Option<usize>>; |
| } |
| |
| impl<T: Read> TryRead for T { |
| fn try_read(&mut self, dst: &mut [u8]) -> io::Result<Option<usize>> { |
| self.read(dst).map_non_block() |
| } |
| } |
| |
| impl<T: Write> TryWrite for T { |
| fn try_write(&mut self, src: &[u8]) -> io::Result<Option<usize>> { |
| self.write(src).map_non_block() |
| } |
| } |
| |
| /* |
| * |
| * ===== Helpers ===== |
| * |
| */ |
| |
| /// A helper trait to provide the map_non_block function on Results. |
| trait MapNonBlock<T> { |
| /// Maps a `Result<T>` to a `Result<Option<T>>` by converting |
| /// operation-would-block errors into `Ok(None)`. |
| fn map_non_block(self) -> io::Result<Option<T>>; |
| } |
| |
| impl<T> MapNonBlock<T> for io::Result<T> { |
| fn map_non_block(self) -> io::Result<Option<T>> { |
| use std::io::ErrorKind::WouldBlock; |
| |
| match self { |
| Ok(value) => Ok(Some(value)), |
| Err(err) => { |
| if let WouldBlock = err.kind() { |
| Ok(None) |
| } else { |
| Err(err) |
| } |
| } |
| } |
| } |
| } |
| |
| pub fn expect_no_events(poll: &mut Poll, events: &mut Events) { |
| poll.poll(events, Some(Duration::from_millis(50))) |
| .expect("unable to poll"); |
| assert!(events.is_empty(), "received events, but didn't expect any"); |
| } |
| |
| /// Bind to any port on localhost. |
| pub fn any_local_address() -> SocketAddr { |
| "127.0.0.1:0".parse().unwrap() |
| } |
| |
| /// Bind to any port on localhost, using a IPv6 address. |
| pub fn any_local_ipv6_address() -> SocketAddr { |
| "[::1]:0".parse().unwrap() |
| } |