diff --git a/examples/simple.rs b/examples/simple.rs index 2cedb890e..066dcc813 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -7,7 +7,7 @@ use std::io::{self, BufRead, Write}; use std::str::FromStr; use sysinfo::Signal::*; -use sysinfo::{Components, Disks, Networks, Pid, Signal, System, UserExt, Users, UsersExt}; +use sysinfo::{Components, Disks, Networks, Pid, Signal, System, Users, UsersExt}; const signals: &[Signal] = &[ Hangup, diff --git a/md_doc/user.md b/md_doc/user.md deleted file mode 100644 index 2c7830464..000000000 --- a/md_doc/user.md +++ /dev/null @@ -1,13 +0,0 @@ -Type containing user information. - -It is returned by [`Users`][crate::Users]. - -```no_run -use sysinfo::{Users, UsersExt}; - -let mut users = Users::new(); -users.refresh_list(); -for user in users.users() { - println!("{:?}", user); -} -``` diff --git a/src/common.rs b/src/common.rs index 99c1ed14f..4f4eea539 100644 --- a/src/common.rs +++ b/src/common.rs @@ -2,7 +2,7 @@ use crate::{ ComponentInner, ComponentsInner, CpuInner, NetworkDataInner, NetworksInner, ProcessInner, - SystemInner, User, UserExt, UsersExt, + SystemInner, UserInner, UsersExt, }; use std::cmp::Ordering; @@ -2209,7 +2209,7 @@ impl std::ops::DerefMut for Components { /// User interfaces. /// /// ```no_run -/// use sysinfo::{Users, UsersExt, UserExt}; +/// use sysinfo::{Users, UsersExt}; /// /// let mut users = Users::new(); /// for user in users.users() { @@ -2484,6 +2484,23 @@ cfg_if::cfg_if! { } } +/// Type containing user information. +/// +/// It is returned by [`Users`][crate::Users]. +/// +/// ```no_run +/// use sysinfo::{Users, UsersExt}; +/// +/// let mut users = Users::new(); +/// users.refresh_list(); +/// for user in users.users() { +/// println!("{:?}", user); +/// } +/// ``` +pub struct User { + pub(crate) inner: UserInner, +} + impl PartialEq for User { fn eq(&self, other: &Self) -> bool { self.id() == other.id() @@ -2506,12 +2523,83 @@ impl Ord for User { } } +impl User { + /// Returns the ID of the user. + /// + /// ```no_run + /// use sysinfo::{Users, UsersExt}; + /// + /// let mut users = Users::new(); + /// users.refresh_list(); + /// for user in users.users() { + /// println!("{:?}", *user.id()); + /// } + /// ``` + pub fn id(&self) -> &Uid { + self.inner.id() + } + + /// Returns the group ID of the user. + /// + /// ⚠️ This information is not set on Windows. Windows doesn't have a `username` specific + /// group assigned to the user. They do however have unique + /// [Security Identifiers](https://docs.microsoft.com/en-us/windows/win32/secauthz/security-identifiers) + /// made up of various [Components](https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-components). + /// Pieces of the SID may be a candidate for this field, but it doesn't map well to a single + /// group ID. + /// + /// ```no_run + /// use sysinfo::{Users, UsersExt}; + /// + /// let mut users = Users::new(); + /// users.refresh_list(); + /// for user in users.users() { + /// println!("{}", *user.group_id()); + /// } + /// ``` + pub fn group_id(&self) -> Gid { + self.inner.group_id() + } + + /// Returns the name of the user. + /// + /// ```no_run + /// use sysinfo::{Users, UsersExt}; + /// + /// let mut users = Users::new(); + /// users.refresh_list(); + /// for user in users.users() { + /// println!("{}", user.name()); + /// } + /// ``` + pub fn name(&self) -> &str { + self.inner.name() + } + + /// Returns the groups of the user. + /// + /// ⚠️ This is computed every time this method is called. + /// + /// ```no_run + /// use sysinfo::{Users, UsersExt}; + /// + /// let mut users = Users::new(); + /// users.refresh_list(); + /// for user in users.users() { + /// println!("{} is in {:?}", user.name(), user.groups()); + /// } + /// ``` + pub fn groups(&self) -> Vec { + self.inner.groups() + } +} + /// Type containing group information. /// /// It is returned by [`User::groups`]. /// /// ```no_run -/// use sysinfo::{UserExt, Users, UsersExt}; +/// use sysinfo::{Users, UsersExt}; /// /// let mut users = Users::new(); /// @@ -2539,7 +2627,7 @@ impl Group { /// ⚠️ This information is not set on Windows. /// /// ```no_run - /// use sysinfo::{UserExt, Users, UsersExt}; + /// use sysinfo::{Users, UsersExt}; /// /// let mut users = Users::new(); /// @@ -2556,7 +2644,7 @@ impl Group { /// Returns the name of the group. /// /// ```no_run - /// use sysinfo::{UserExt, Users, UsersExt}; + /// use sysinfo::{Users, UsersExt}; /// /// let mut users = Users::new(); /// diff --git a/src/debug.rs b/src/debug.rs index dc3cfcc02..0cd0c6fb6 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -1,8 +1,7 @@ // Take a look at the license at the top of the repository in the LICENSE file. use crate::{ - Component, Components, Cpu, Disk, Disks, NetworkData, Networks, Process, System, User, UserExt, - Users, + Component, Components, Cpu, Disk, Disks, NetworkData, Networks, Process, System, User, Users, }; use std::fmt; diff --git a/src/lib.rs b/src/lib.rs index d86ca288f..2d433d817 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,15 +54,15 @@ cfg_if::cfg_if! { pub use crate::common::{ get_current_pid, Component, Components, Cpu, CpuRefreshKind, Disk, DiskKind, DiskUsage, Disks, Gid, Group, LoadAvg, MacAddr, NetworkData, Networks, NetworksIter, Pid, PidExt, Process, - ProcessRefreshKind, ProcessStatus, RefreshKind, Signal, System, Uid, Users, + ProcessRefreshKind, ProcessStatus, RefreshKind, Signal, System, Uid, User, Users, }; pub(crate) use crate::sys::{ ComponentInner, ComponentsInner, CpuInner, DiskInner, DisksInner, NetworkDataInner, - NetworksInner, ProcessInner, SystemInner, + NetworksInner, ProcessInner, SystemInner, UserInner, }; -pub use crate::sys::{User, IS_SUPPORTED, MINIMUM_CPU_UPDATE_INTERVAL, SUPPORTED_SIGNALS}; -pub use crate::traits::{UserExt, UsersExt}; +pub use crate::sys::{IS_SUPPORTED, MINIMUM_CPU_UPDATE_INTERVAL, SUPPORTED_SIGNALS}; +pub use crate::traits::UsersExt; #[cfg(feature = "c-interface")] pub use crate::c_interface::*; diff --git a/src/serde.rs b/src/serde.rs index 01e07974c..a533d5709 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -1,7 +1,7 @@ // Take a look at the license at the top of the repository in the LICENSE file. use crate::common::PidExt; -use crate::{DiskKind, DiskUsage, MacAddr, ProcessStatus, Signal, UserExt}; +use crate::{DiskKind, DiskUsage, MacAddr, ProcessStatus, Signal}; use serde::{ser::SerializeStruct, Serialize, Serializer}; use std::ops::Deref; diff --git a/src/traits.rs b/src/traits.rs index f8eea8e2a..eff52f715 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,86 +1,10 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use crate::common::{Gid, Uid}; -use crate::{Group, User}; +use crate::common::Uid; +use crate::User; use std::fmt::Debug; -/// Getting information for a user. -/// -/// It is returned from [`UsersExt::users`]. -/// -/// ```no_run -/// use sysinfo::{Users, UsersExt, UserExt}; -/// -/// let mut users = Users::new(); -/// users.refresh_list(); -/// for user in users.users() { -/// println!("{} is in {} groups", user.name(), user.groups().len()); -/// } -/// ``` -pub trait UserExt: Debug + PartialEq + Eq + PartialOrd + Ord { - /// Returns the ID of the user. - /// - /// ```no_run - /// use sysinfo::{Users, UsersExt, UserExt}; - /// - /// let mut users = Users::new(); - /// users.refresh_list(); - /// for user in users.users() { - /// println!("{:?}", *user.id()); - /// } - /// ``` - fn id(&self) -> &Uid; - - /// Returns the group ID of the user. - /// - /// ⚠️ This information is not set on Windows. Windows doesn't have a `username` specific - /// group assigned to the user. They do however have unique - /// [Security Identifiers](https://docs.microsoft.com/en-us/windows/win32/secauthz/security-identifiers) - /// made up of various [Components](https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-components). - /// Pieces of the SID may be a candidate for this field, but it doesn't map well to a single - /// group ID. - /// - /// ```no_run - /// use sysinfo::{Users, UsersExt, UserExt}; - /// - /// let mut users = Users::new(); - /// users.refresh_list(); - /// for user in users.users() { - /// println!("{}", *user.group_id()); - /// } - /// ``` - fn group_id(&self) -> Gid; - - /// Returns the name of the user. - /// - /// ```no_run - /// use sysinfo::{Users, UsersExt, UserExt}; - /// - /// let mut users = Users::new(); - /// users.refresh_list(); - /// for user in users.users() { - /// println!("{}", user.name()); - /// } - /// ``` - fn name(&self) -> &str; - - /// Returns the groups of the user. - /// - /// ⚠️ This is computed every time this method is called. - /// - /// ```no_run - /// use sysinfo::{Users, UsersExt, UserExt}; - /// - /// let mut users = Users::new(); - /// users.refresh_list(); - /// for user in users.users() { - /// println!("{} is in {:?}", user.name(), user.groups()); - /// } - /// ``` - fn groups(&self) -> Vec; -} - /// Interacting with users. /// /// ```no_run @@ -122,7 +46,7 @@ pub trait UsersExt: Debug { /// Returns the users list. /// /// ```no_run - /// use sysinfo::{UserExt, Users, UsersExt}; + /// use sysinfo::{Users, UsersExt}; /// /// let mut users = Users::new(); /// users.refresh_list(); @@ -140,7 +64,7 @@ pub trait UsersExt: Debug { /// You can do the same without this method by calling: /// /// ```no_run - /// use sysinfo::{UserExt, Users, UsersExt}; + /// use sysinfo::{Users, UsersExt}; /// /// let mut users = Users::new(); /// users.refresh_list(); @@ -176,7 +100,7 @@ pub trait UsersExt: Debug { /// It is a shorthand for: /// /// ```ignore - /// # use sysinfo::{UserExt, Users, UsersExt}; + /// # use sysinfo::{Users, UsersExt}; /// let mut users = Users::new(); /// users.refresh_list(); /// users.users().find(|user| user.id() == user_id); diff --git a/src/unix/apple/mod.rs b/src/unix/apple/mod.rs index d2a9f8cd5..d84dbcfb9 100644 --- a/src/unix/apple/mod.rs +++ b/src/unix/apple/mod.rs @@ -30,8 +30,7 @@ pub(crate) use self::disk::DiskInner; pub(crate) use self::network::{NetworkDataInner, NetworksInner}; pub(crate) use self::process::ProcessInner; pub(crate) use self::system::SystemInner; -pub(crate) use crate::unix::users::get_users; -pub use crate::unix::users::User; +pub(crate) use crate::unix::users::{get_users, UserInner}; pub(crate) use crate::unix::DisksInner; use std::time::Duration; diff --git a/src/unix/apple/users.rs b/src/unix/apple/users.rs index 254c70d3e..ed3de17a2 100644 --- a/src/unix/apple/users.rs +++ b/src/unix/apple/users.rs @@ -2,7 +2,7 @@ use crate::{ common::{Gid, Uid}, - User, + User, UserInner, }; use libc::{c_char, endpwent, getpwent, setpwent, strlen}; @@ -61,7 +61,9 @@ pub(crate) fn get_users(users: &mut Vec) { endpwent(); } for (name, (uid, gid)) in users_map { - users.push(User::new(uid, gid, name)); + users.push(User { + inner: UserInner::new(uid, gid, name), + }); } } diff --git a/src/unix/freebsd/mod.rs b/src/unix/freebsd/mod.rs index cef20ef04..db6e29efc 100644 --- a/src/unix/freebsd/mod.rs +++ b/src/unix/freebsd/mod.rs @@ -14,8 +14,7 @@ pub(crate) use self::disk::DiskInner; pub(crate) use self::network::{NetworkDataInner, NetworksInner}; pub(crate) use self::process::ProcessInner; pub(crate) use self::system::SystemInner; -pub(crate) use crate::unix::users::get_users; -pub use crate::unix::users::User; +pub(crate) use crate::unix::users::{get_users, UserInner}; pub(crate) use crate::unix::DisksInner; use libc::c_int; diff --git a/src/unix/linux/mod.rs b/src/unix/linux/mod.rs index 1750b6580..b13d5b87c 100644 --- a/src/unix/linux/mod.rs +++ b/src/unix/linux/mod.rs @@ -14,8 +14,7 @@ pub(crate) use self::disk::DiskInner; pub(crate) use self::network::{NetworkDataInner, NetworksInner}; pub(crate) use self::process::ProcessInner; pub(crate) use self::system::SystemInner; -pub(crate) use crate::unix::users::get_users; -pub use crate::unix::users::User; +pub(crate) use crate::unix::users::{get_users, UserInner}; pub(crate) use crate::unix::DisksInner; use std::time::Duration; diff --git a/src/unix/users.rs b/src/unix/users.rs index 2caf0fd05..e8ef32d07 100644 --- a/src/unix/users.rs +++ b/src/unix/users.rs @@ -2,20 +2,22 @@ use crate::{ common::{Gid, Uid}, - Group, UserExt, + Group, }; +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +use crate::User; + use libc::{getgrgid_r, getgrouplist}; -#[doc = include_str!("../../md_doc/user.md")] -pub struct User { +pub(crate) struct UserInner { pub(crate) uid: Uid, pub(crate) gid: Gid, pub(crate) name: String, c_user: Vec, } -impl User { +impl UserInner { pub(crate) fn new(uid: Uid, gid: Gid, name: String) -> Self { let mut c_user = name.as_bytes().to_vec(); c_user.push(0); @@ -26,22 +28,20 @@ impl User { c_user, } } -} -impl UserExt for User { - fn id(&self) -> &Uid { + pub(crate) fn id(&self) -> &Uid { &self.uid } - fn group_id(&self) -> Gid { + pub(crate) fn group_id(&self) -> Gid { self.gid } - fn name(&self) -> &str { + pub(crate) fn name(&self) -> &str { &self.name } - fn groups(&self) -> Vec { + pub(crate) fn groups(&self) -> Vec { unsafe { get_user_groups(self.c_user.as_ptr() as *const _, self.gid.0 as _) } } } @@ -131,7 +131,9 @@ pub(crate) fn get_users(users: &mut Vec) { // Skip the user if the uid cannot be parsed correctly if let Some(uid) = parts.next().and_then(parse_id) { if let Some(group_id) = parts.next().and_then(parse_id) { - users.push(User::new(Uid(uid), Gid(group_id), username.to_owned())); + users.push(User { + inner: UserInner::new(Uid(uid), Gid(group_id), username.to_owned()), + }); } } } diff --git a/src/unknown/users.rs b/src/unknown/users.rs index aa4d2c734..0bf378bdf 100644 --- a/src/unknown/users.rs +++ b/src/unknown/users.rs @@ -1,24 +1,23 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use crate::{Gid, Group, Uid, UserExt}; +use crate::{Gid, Group, Uid, User}; -#[doc = include_str!("../../md_doc/user.md")] -pub struct User; +pub(crate) struct UserInner; -impl UserExt for User { - fn id(&self) -> &Uid { +impl UserInner { + pub(crate) fn id(&self) -> &Uid { &Uid(0) } - fn group_id(&self) -> Gid { + pub(crate) fn group_id(&self) -> Gid { Gid(0) } - fn name(&self) -> &str { + pub(crate) fn name(&self) -> &str { "" } - fn groups(&self) -> Vec { + pub(crate) fn groups(&self) -> Vec { Vec::new() } } diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 951ec01e2..cadc7ebf9 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -20,7 +20,7 @@ pub(crate) use self::process::ProcessInner; pub use self::sid::Sid; pub(crate) use self::system::SystemInner; pub(crate) use self::users::get_users; -pub use self::users::User; +pub(crate) use self::users::UserInner; use std::time::Duration; diff --git a/src/windows/users.rs b/src/windows/users.rs index 5118f3c91..6a3317fa4 100644 --- a/src/windows/users.rs +++ b/src/windows/users.rs @@ -4,7 +4,7 @@ use crate::sys::utils::to_str; use crate::{ common::{Gid, Uid}, windows::sid::Sid, - Group, UserExt, + Group, User, }; use std::ptr::null_mut; @@ -20,8 +20,7 @@ use windows::Win32::Security::Authentication::Identity::{ SECURITY_LOGON_SESSION_DATA, SECURITY_LOGON_TYPE, }; -#[doc = include_str!("../../md_doc/user.md")] -pub struct User { +pub(crate) struct UserInner { pub(crate) uid: Uid, pub(crate) gid: Gid, pub(crate) name: String, @@ -29,7 +28,7 @@ pub struct User { is_local: bool, } -impl User { +impl UserInner { fn new(uid: Uid, name: String, c_name: PCWSTR, is_local: bool) -> Self { let c_user_name = if c_name.is_null() { None @@ -44,22 +43,20 @@ impl User { is_local, } } -} -impl UserExt for User { - fn id(&self) -> &Uid { + pub(crate) fn id(&self) -> &Uid { &self.uid } - fn group_id(&self) -> Gid { + pub(crate) fn group_id(&self) -> Gid { self.gid } - fn name(&self) -> &str { + pub(crate) fn name(&self) -> &str { &self.name } - fn groups(&self) -> Vec { + pub(crate) fn groups(&self) -> Vec { if let (Some(c_user_name), true) = (&self.c_user_name, self.is_local) { unsafe { get_groups_for_user(PCWSTR(c_user_name.as_ptr())) } } else { @@ -195,12 +192,14 @@ pub(crate) fn get_users(users: &mut Vec) { let name = sid .account_name() .unwrap_or_else(|| to_str(entry.usri0_name)); - users.push(User::new( - Uid(sid), - name, - PCWSTR(entry.usri0_name.0 as *const _), - true, - )) + users.push(User { + inner: UserInner::new( + Uid(sid), + name, + PCWSTR(entry.usri0_name.0 as *const _), + true, + ), + }); } } } @@ -241,7 +240,7 @@ pub(crate) fn get_users(users: &mut Vec) { None => continue, }; - if users.iter().any(|u| u.uid.0 == sid) { + if users.iter().any(|u| u.inner.uid.0 == sid) { continue; } @@ -259,7 +258,9 @@ pub(crate) fn get_users(users: &mut Vec) { }) }); - users.push(User::new(Uid(sid), name, PCWSTR::null(), false)); + users.push(User { + inner: UserInner::new(Uid(sid), name, PCWSTR::null(), false), + }); } } }