Skip to content

Commit

Permalink
Add extra traits for all types
Browse files Browse the repository at this point in the history
Derive Clone, Copy, Eq, Hash, and PartialEq for all types. Not all
traits are supported by all types, which is why many are missing
some.
  • Loading branch information
Susurrus committed Jun 4, 2019
1 parent 32e52f3 commit c3b1d2e
Show file tree
Hide file tree
Showing 27 changed files with 68 additions and 572 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).

ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
```
- Implemented `Clone`, `Copy`, `Debug`, `Eq`, `Hash`, and `PartialEq` for most
types that support them. ([#1035](https://github.com/nix-rust/nix/pull/1035))

### Changed
- Minimum supported Rust version is now 1.25.0
Expand Down
27 changes: 5 additions & 22 deletions src/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use errno::Errno;
use fcntl::{self, OFlag};
use libc;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
use std::{ffi, fmt, ptr};
use std::{ffi, ptr};
use sys;

#[cfg(target_os = "linux")]
Expand All @@ -25,6 +25,7 @@ use libc::{dirent, readdir_r};
/// * returns entries for `.` (current directory) and `..` (parent directory).
/// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc
/// does).
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Dir(
// This could be ptr::NonNull once nix requires Rust 1.25.
*mut libc::DIR
Expand Down Expand Up @@ -82,21 +83,13 @@ impl AsRawFd for Dir {
}
}

impl fmt::Debug for Dir {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Dir")
.field("fd", &self.as_raw_fd())
.finish()
}
}

impl Drop for Dir {
fn drop(&mut self) {
unsafe { libc::closedir(self.0) };
}
}

#[derive(Debug)]
#[derive(Debug, Eq, Hash, PartialEq)]
pub struct Iter<'d>(&'d mut Dir);

impl<'d> Iterator for Iter<'d> {
Expand Down Expand Up @@ -132,10 +125,10 @@ impl<'d> Drop for Iter<'d> {
/// A directory entry, similar to `std::fs::DirEntry`.
///
/// Note that unlike the std version, this may represent the `.` or `..` entries.
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub struct Entry(dirent);

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum Type {
Fifo,
CharacterDevice,
Expand Down Expand Up @@ -198,13 +191,3 @@ impl Entry {
}
}
}

impl fmt::Debug for Entry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Entry")
.field("ino", &self.ino())
.field("file_name", &self.file_name())
.field("file_type", &self.file_type())
.finish()
}
}
5 changes: 2 additions & 3 deletions src/fcntl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ libc_bitflags!(
}
);

#[allow(missing_debug_implementations)]
#[derive(Debug, Eq, Hash, PartialEq)]
pub enum FcntlArg<'a> {
F_DUPFD(RawFd),
F_DUPFD_CLOEXEC(RawFd),
Expand Down Expand Up @@ -277,8 +277,7 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
Errno::result(res)
}

#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum FlockArg {
LockShared,
LockExclusive,
Expand Down
2 changes: 1 addition & 1 deletion src/ifaddrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use sys::socket::SockAddr;
use net::if_::*;

/// Describes a single address for an interface as returned by `getifaddrs`.
#[derive(Clone, Eq, Hash, PartialEq, Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct InterfaceAddress {
/// Name of the network interface
pub interface_name: String,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub type Result<T> = result::Result<T, Error>;
/// error has a corresponding errno (usually the one from the
/// underlying OS) to which it can be mapped in addition to
/// implementing other common traits.
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Error {
Sys(Errno),
InvalidPath,
Expand Down
13 changes: 1 addition & 12 deletions src/mqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,11 @@ libc_bitflags!{
}

#[repr(C)]
#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct MqAttr {
mq_attr: libc::mq_attr,
}

impl PartialEq<MqAttr> for MqAttr {
fn eq(&self, other: &MqAttr) -> bool {
let self_attr = self.mq_attr;
let other_attr = other.mq_attr;
self_attr.mq_flags == other_attr.mq_flags && self_attr.mq_maxmsg == other_attr.mq_maxmsg &&
self_attr.mq_msgsize == other_attr.mq_msgsize &&
self_attr.mq_curmsgs == other_attr.mq_curmsgs
}
}

impl MqAttr {
pub fn new(mq_flags: c_long,
mq_maxmsg: c_long,
Expand Down
20 changes: 1 addition & 19 deletions src/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use sys::time::TimeSpec;
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
use sys::signal::SigSet;
use std::os::unix::io::RawFd;
use std::fmt;

use libc;
use Result;
Expand All @@ -19,7 +18,7 @@ use errno::Errno;
/// After a call to `poll` or `ppoll`, the events that occured can be
/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
#[repr(C)]
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct PollFd {
pollfd: libc::pollfd,
}
Expand All @@ -43,23 +42,6 @@ impl PollFd {
}
}

impl fmt::Debug for PollFd {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let pfd = self.pollfd;
let mut ds = f.debug_struct("PollFd");
ds.field("fd", &pfd.fd);
match PollFlags::from_bits(pfd.events) {
None => ds.field("events", &pfd.events),
Some(ef) => ds.field("events", &ef),
};
match PollFlags::from_bits(pfd.revents) {
None => ds.field("revents", &pfd.revents),
Some(ef) => ds.field("revents", &ef),
};
ds.finish()
}
}

libc_bitflags! {
/// These flags define the different events that can be monitored by `poll` and `ppoll`
pub struct PollFlags: libc::c_short {
Expand Down
5 changes: 2 additions & 3 deletions src/pty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ use errno::Errno;
///
/// This is returned by `openpty`. Note that this type does *not* implement `Drop`, so the user
/// must manually close the file descriptors.
#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct OpenptyResult {
/// The master port in a virtual pty pair
pub master: RawFd,
Expand All @@ -45,7 +44,7 @@ pub struct ForkptyResult {
/// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY
/// functions are given the correct file descriptor. Additionally this type implements `Drop`,
/// so that when it's consumed or goes out of scope, it's automatically cleaned-up.
#[derive(Debug)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct PtyMaster(RawFd);

impl AsRawFd for PtyMaster {
Expand Down
3 changes: 1 addition & 2 deletions src/sched.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ libc_bitflags!{
pub type CloneCb<'a> = Box<FnMut() -> isize + 'a>;

#[repr(C)]
#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct CpuSet {
cpu_set: libc::cpu_set_t,
}
Expand Down
19 changes: 2 additions & 17 deletions src/sys/aio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ libc_enum! {
/// Return values for [`AioCb::cancel`](struct.AioCb.html#method.cancel) and
/// [`aio_cancel_all`](fn.aio_cancel_all.html)
#[repr(i32)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum AioCancelStat {
/// All outstanding requests were canceled
AioCanceled = libc::AIO_CANCELED,
Expand Down Expand Up @@ -133,6 +133,7 @@ impl<'a> Debug for Buffer<'a> {
///
/// The basic structure used by all aio functions. Each `AioCb` represents one
/// I/O request.
#[derive(Debug)]
pub struct AioCb<'a> {
aiocb: libc::aiocb,
/// Tracks whether the buffer pointed to by `libc::aiocb.aio_buf` is mutable
Expand Down Expand Up @@ -1018,22 +1019,6 @@ pub fn aio_suspend(list: &[&AioCb], timeout: Option<TimeSpec>) -> Result<()> {
}).map(drop)
}

impl<'a> Debug for AioCb<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("AioCb")
.field("aio_fildes", &self.aiocb.aio_fildes)
.field("aio_offset", &self.aiocb.aio_offset)
.field("aio_buf", &self.aiocb.aio_buf)
.field("aio_nbytes", &self.aiocb.aio_nbytes)
.field("aio_lio_opcode", &self.aiocb.aio_lio_opcode)
.field("aio_reqprio", &self.aiocb.aio_reqprio)
.field("aio_sigevent", &SigEvent::from(&self.aiocb.aio_sigevent))
.field("mutable", &self.mutable)
.field("in_progress", &self.in_progress)
.finish()
}
}

impl<'a> Drop for AioCb<'a> {
/// If the `AioCb` has no remaining state in the kernel, just drop it.
/// Otherwise, dropping constitutes a resource leak, which is an error
Expand Down
3 changes: 1 addition & 2 deletions src/sys/epoll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ libc_bitflags!{
}
}

#[allow(missing_debug_implementations)]
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(C)]
pub struct EpollEvent {
event: libc::epoll_event,
Expand Down
3 changes: 1 addition & 2 deletions src/sys/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ use std::ptr;
use std::mem;

// Redefine kevent in terms of programmer-friendly enums and bitfields.
#[derive(Clone, Copy)]
#[repr(C)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct KEvent {
kevent: libc::kevent,
}
Expand Down
3 changes: 1 addition & 2 deletions src/sys/quota.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ libc_bitflags!(
/// Wrapper type for `if_dqblk`
// FIXME: Change to repr(transparent)
#[repr(C)]
#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Dqblk(libc::dqblk);

impl Default for Dqblk {
Expand Down
3 changes: 1 addition & 2 deletions src/sys/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ pub use libc::FD_SETSIZE;

// FIXME: Change to repr(transparent) once it's stable
#[repr(C)]
#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct FdSet(libc::fd_set);

impl FdSet {
Expand Down
2 changes: 1 addition & 1 deletion src/sys/sendfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ cfg_if! {
target_os = "macos"))] {
use sys::uio::IoVec;

#[allow(missing_debug_implementations)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct SendfileHeaderTrailer<'a>(
libc::sf_hdtr,
Option<Vec<IoVec<&'a [u8]>>>,
Expand Down
38 changes: 6 additions & 32 deletions src/sys/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,7 @@ const SIGNALS: [Signal; 31] = [

pub const NSIG: libc::c_int = 32;

#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct SignalIterator {
next: usize,
}
Expand Down Expand Up @@ -328,8 +327,7 @@ libc_enum! {
}
}

#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct SigSet {
sigset: libc::sigset_t
}
Expand Down Expand Up @@ -427,7 +425,7 @@ impl AsRef<libc::sigset_t> for SigSet {

/// A signal handler.
#[allow(unknown_lints)]
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SigHandler {
/// Default signal handling.
SigDfl,
Expand All @@ -441,8 +439,7 @@ pub enum SigHandler {
}

/// Action to take on receipt of a signal. Corresponds to `sigaction`.
#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct SigAction {
sigaction: libc::sigaction
}
Expand Down Expand Up @@ -683,7 +680,7 @@ pub type type_of_thread_id = libc::pid_t;
// sigval is actually a union of a int and a void*. But it's never really used
// as a pointer, because neither libc nor the kernel ever dereference it. nix
// therefore presents it as an intptr_t, which is how kevent uses it.
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SigevNotify {
/// No notification will be delivered
SigevNone,
Expand All @@ -710,15 +707,14 @@ mod sigevent {
use libc;
use std::mem;
use std::ptr;
use std::fmt::{self, Debug};
use super::SigevNotify;
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
use super::type_of_thread_id;

/// Used to request asynchronous notification of the completion of certain
/// events, such as POSIX AIO and timers.
#[repr(C)]
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct SigEvent {
sigevent: libc::sigevent
}
Expand Down Expand Up @@ -788,28 +784,6 @@ mod sigevent {
}
}

impl Debug for SigEvent {
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("SigEvent")
.field("sigev_notify", &self.sigevent.sigev_notify)
.field("sigev_signo", &self.sigevent.sigev_signo)
.field("sigev_value", &self.sigevent.sigev_value.sival_ptr)
.field("sigev_notify_thread_id",
&self.sigevent.sigev_notify_thread_id)
.finish()
}

#[cfg(not(any(target_os = "freebsd", target_os = "linux")))]
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("SigEvent")
.field("sigev_notify", &self.sigevent.sigev_notify)
.field("sigev_signo", &self.sigevent.sigev_signo)
.field("sigev_value", &self.sigevent.sigev_value.sival_ptr)
.finish()
}
}

impl<'a> From<&'a libc::sigevent> for SigEvent {
fn from(sigevent: &libc::sigevent) -> Self {
SigEvent{ sigevent: *sigevent }
Expand Down
Loading

0 comments on commit c3b1d2e

Please sign in to comment.