From ed23af16ca206c67ba4106fd8dbf69d67e46744b Mon Sep 17 00:00:00 2001
From: Bryant Mairs <bryant@mai.rs>
Date: Fri, 22 Feb 2019 07:56:34 -0800
Subject: [PATCH] Add extra traits for dragonfly datatypes

---
 src/unix/bsd/freebsdlike/dragonfly/mod.rs | 178 +++++++++++++++++++++-
 1 file changed, 175 insertions(+), 3 deletions(-)

diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs
index 7c96ebcf..f0cbef9c 100644
--- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs
+++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs
@@ -177,7 +177,6 @@ s! {
 }
 
 s_no_extra_traits! {
-    #[allow(missing_debug_implementations)]
     pub struct utmpx {
         pub ut_name: [::c_char; 32],
         pub ut_id: [::c_char; 4],
@@ -195,7 +194,6 @@ s_no_extra_traits! {
         pub ut_unused2: [u8; 16],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct dirent {
         pub d_fileno: ::ino_t,
         pub d_namlen: u16,
@@ -205,7 +203,6 @@ s_no_extra_traits! {
         pub d_name: [::c_char; 256],
     }
 
-    #[allow(missing_debug_implementations)]
     pub struct statfs {
         pub f_bsize: ::c_long,
         pub f_iosize: ::c_long,
@@ -228,6 +225,181 @@ s_no_extra_traits! {
     }
 }
 
+cfg_if! {
+    if #[cfg(feature = "extra_traits")] {
+        impl PartialEq for utmpx {
+            fn eq(&self, other: &utmpx) -> bool {
+                self.ut_name == other.ut_name
+                    && self.ut_id == other.ut_id
+                    && self.ut_line == other.ut_line
+                    && self
+                    .ut_host
+                    .iter()
+                    .zip(other.ut_host.iter())
+                    .all(|(a,b)| a == b)
+                    && self.ut_unused == other.ut_unused
+                    && self.ut_session == other.ut_session
+                    && self.ut_type == other.ut_type
+                    && self.ut_pid == other.ut_pid
+                    && self.ut_exit == other.ut_exit
+                    && self.ut_ss == other.ut_ss
+                    && self.ut_tv == other.ut_tv
+                    && self.ut_unused2 == other.ut_unused2
+            }
+        }
+        impl Eq for utmpx {}
+        impl ::fmt::Debug for utmpx {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("utmpx")
+                    .field("ut_name", &self.ut_name)
+                    .field("ut_id", &self.ut_id)
+                    .field("ut_line", &self.ut_line)
+                    // FIXME: .field("ut_host", &self.ut_host)
+                    .field("ut_unused", &self.ut_unused)
+                    .field("ut_session", &self.ut_session)
+                    .field("ut_type", &self.ut_type)
+                    .field("ut_pid", &self.ut_pid)
+                    .field("ut_exit", &self.ut_exit)
+                    .field("ut_ss", &self.ut_ss)
+                    .field("ut_tv", &self.ut_tv)
+                    .field("ut_unused2", &self.ut_unused2)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for utmpx {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.ut_name.hash(state);
+                self.ut_id.hash(state);
+                self.ut_line.hash(state);
+                self.ut_host.hash(state);
+                self.ut_unused.hash(state);
+                self.ut_session.hash(state);
+                self.ut_type.hash(state);
+                self.ut_pid.hash(state);
+                self.ut_exit.hash(state);
+                self.ut_ss.hash(state);
+                self.ut_tv.hash(state);
+                self.ut_unused2.hash(state);
+            }
+        }
+
+        impl PartialEq for dirent {
+            fn eq(&self, other: &dirent) -> bool {
+                self.d_fileno == other.d_fileno
+                    && self.d_namlen == other.d_namlen
+                    && self.d_type == other.d_type
+                    // Ignore __unused1
+                    // Ignore __unused2
+                    && self
+                    .d_name
+                    .iter()
+                    .zip(other.d_name.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for dirent {}
+        impl ::fmt::Debug for dirent {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("dirent")
+                    .field("d_fileno", &self.d_fileno)
+                    .field("d_namlen", &self.d_namlen)
+                    .field("d_type", &self.d_type)
+                    // Ignore __unused1
+                    // Ignore __unused2
+                    // FIXME: .field("d_name", &self.d_name)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for dirent {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.d_fileno.hash(state);
+                self.d_namlen.hash(state);
+                self.d_type.hash(state);
+                    // Ignore __unused1
+                    // Ignore __unused2
+                self.d_name.hash(state);
+            }
+        }
+
+        impl PartialEq for statfs {
+            fn eq(&self, other: &statfs) -> bool {
+                self.f_bsize == other.f_bsize
+                    && self.f_iosize == other.f_iosize
+                    && self.f_blocks == other.f_blocks
+                    && self.f_bfree == other.f_bfree
+                    && self.f_bavail == other.f_bavail
+                    && self.f_files == other.f_files
+                    && self.f_ffree == other.f_ffree
+                    && self.f_fsid == other.f_fsid
+                    && self.f_owner == other.f_owner
+                    && self.f_type == other.f_type
+                    && self.f_flags == other.f_flags
+                    && self.f_syncwrites == other.f_syncwrites
+                    && self.f_asyncwrites == other.f_asyncwrites
+                    && self.f_fstypename == other.f_fstypename
+                    && self
+                    .f_mntonname
+                    .iter()
+                    .zip(other.f_mntonname.iter())
+                    .all(|(a,b)| a == b)
+                    && self.f_syncreads == other.f_syncreads
+                    && self.f_asyncreads == other.f_asyncreads
+                    && self
+                    .f_mntfromname
+                    .iter()
+                    .zip(other.f_mntfromname.iter())
+                    .all(|(a,b)| a == b)
+            }
+        }
+        impl Eq for statfs {}
+        impl ::fmt::Debug for statfs {
+            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+                f.debug_struct("statfs")
+                    .field("f_bsize", &self.f_bsize)
+                    .field("f_iosize", &self.f_iosize)
+                    .field("f_blocks", &self.f_blocks)
+                    .field("f_bfree", &self.f_bfree)
+                    .field("f_bavail", &self.f_bavail)
+                    .field("f_files", &self.f_files)
+                    .field("f_ffree", &self.f_ffree)
+                    .field("f_fsid", &self.f_fsid)
+                    .field("f_owner", &self.f_owner)
+                    .field("f_type", &self.f_type)
+                    .field("f_flags", &self.f_flags)
+                    .field("f_syncwrites", &self.f_syncwrites)
+                    .field("f_asyncwrites", &self.f_asyncwrites)
+                    // FIXME: .field("f_mntonname", &self.f_mntonname)
+                    .field("f_syncreads", &self.f_syncreads)
+                    .field("f_asyncreads", &self.f_asyncreads)
+                    // FIXME: .field("f_mntfromname", &self.f_mntfromname)
+                    .finish()
+            }
+        }
+        impl ::hash::Hash for statfs {
+            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+                self.f_bsize.hash(state);
+                self.f_iosize.hash(state);
+                self.f_blocks.hash(state);
+                self.f_bfree.hash(state);
+                self.f_bavail.hash(state);
+                self.f_files.hash(state);
+                self.f_ffree.hash(state);
+                self.f_fsid.hash(state);
+                self.f_owner.hash(state);
+                self.f_type.hash(state);
+                self.f_flags.hash(state);
+                self.f_syncwrites.hash(state);
+                self.f_asyncwrites.hash(state);
+                self.f_fstypename.hash(state);
+                self.f_mntonname.hash(state);
+                self.f_syncreads.hash(state);
+                self.f_asyncreads.hash(state);
+                self.f_mntfromname.hash(state);
+            }
+        }
+    }
+}
+
 pub const RAND_MAX: ::c_int = 0x7fff_ffff;
 pub const PTHREAD_STACK_MIN: ::size_t = 16384;
 pub const SIGSTKSZ: ::size_t = 40960;
-- 
GitLab