Skip to content

Commit

Permalink
Replace User fields with getters
Browse files Browse the repository at this point in the history
The name() accessor is able to hide the fact that the user's actual name string is hidden in an Arc. (The Arc is still available, since it's needed for caching)
  • Loading branch information
ogham committed Jan 28, 2016
1 parent 305b37e commit fefddc4
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 35 deletions.
4 changes: 2 additions & 2 deletions examples/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ fn main() {
println!("Your UID is {}", current_uid);

let you = cache.get_user_by_uid(current_uid).expect("No entry for current user!");
println!("Your username is {}", you.name);
println!("Your username is {}", you.name());

let primary_group = cache.get_group_by_gid(you.primary_group).expect("No entry for your primary group!");
let primary_group = cache.get_group_by_gid(you.primary_group_id()).expect("No entry for your primary group!");
println!("Your primary group has ID {} and name {}", primary_group.gid, primary_group.name);

if primary_group.members.is_empty() {
Expand Down
4 changes: 2 additions & 2 deletions examples/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ fn main() {
println!("Your UID is {}", current_uid);

let you = cache.get_user_by_uid(current_uid).expect("No entry for current user!");
println!("Your username is {}", you.name);
println!("Your username is {}", you.name());
println!("Your shell is {}", you.shell().display());
println!("Your home directory is {}", you.home_dir().display());

let primary_group = cache.get_group_by_gid(you.primary_group).expect("No entry for your primary group!");
let primary_group = cache.get_group_by_gid(you.primary_group_id()).expect("No entry for your primary group!");
println!("Your primary group has ID {} and name {}", primary_group.gid, primary_group.name);

if primary_group.members.is_empty() {
Expand Down
2 changes: 1 addition & 1 deletion examples/threading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn main() {
for uid in LO .. HI {
let cache = cache.lock().unwrap(); // Re-unlock the mutex
if let Some(u) = cache.get_user_by_uid(uid) { // Re-query our cache!
println!("User #{} is {}", u.uid, u.name)
println!("User #{} is {}", u.uid(), u.name())
}
else {
println!("User #{} does not exist", uid);
Expand Down
37 changes: 21 additions & 16 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,9 @@ extern {
/// Information about a particular user.
#[derive(Clone)]
pub struct User {

/// This user's ID
pub uid: uid_t,

/// This user's name
pub name: Arc<String>,

/// The ID of this user's primary group
pub primary_group: gid_t,

uid: uid_t,
pub name_arc: Arc<String>,
primary_group: gid_t,
extras: os::UserExtras,
}

Expand All @@ -119,11 +112,23 @@ impl User {
pub fn new(uid: uid_t, name: &str, primary_group: gid_t) -> User {
User {
uid: uid,
name: Arc::new(name.to_owned()),
name_arc: Arc::new(name.to_owned()),
primary_group: primary_group,
extras: os::UserExtras::default(),
}
}

pub fn uid(&self) -> uid_t {
self.uid.clone()
}

pub fn name(&self) -> &str {
&**self.name_arc
}

pub fn primary_group_id(&self) -> gid_t {
self.primary_group.clone()
}
}

/// Information about a particular group.
Expand Down Expand Up @@ -171,7 +176,7 @@ unsafe fn passwd_to_user(pointer: *const c_passwd) -> Option<User> {

Some(User {
uid: passwd.pw_uid,
name: name,
name_arc: name,
primary_group: passwd.pw_gid,
extras: os::UserExtras::from_passwd(passwd),
})
Expand Down Expand Up @@ -282,7 +287,7 @@ pub fn get_current_uid() -> uid_t {
/// Returns the username of the user running the process.
pub fn get_current_username() -> Option<String> {
let uid = get_current_uid();
get_user_by_uid(uid).map(|u| Arc::try_unwrap(u.name).unwrap())
get_user_by_uid(uid).map(|u| Arc::try_unwrap(u.name_arc).unwrap())
}

/// Returns the user ID for the effective user running the process.
Expand All @@ -293,7 +298,7 @@ pub fn get_effective_uid() -> uid_t {
/// Returns the username of the effective user running the process.
pub fn get_effective_username() -> Option<String> {
let uid = get_effective_uid();
get_user_by_uid(uid).map(|u| Arc::try_unwrap(u.name).unwrap())
get_user_by_uid(uid).map(|u| Arc::try_unwrap(u.name_arc).unwrap())
}

/// Returns the group ID for the user running the process.
Expand Down Expand Up @@ -527,7 +532,7 @@ mod test {
#[test]
fn username() {
let uid = get_current_uid();
assert_eq!(&*get_current_username().unwrap(), &*get_user_by_uid(uid).unwrap().name);
assert_eq!(&*get_current_username().unwrap(), &*get_user_by_uid(uid).unwrap().name());
}

#[test]
Expand Down Expand Up @@ -563,7 +568,7 @@ mod test {
let name = get_current_username().unwrap();
let user_by_name = get_user_by_name(&name);
assert!(user_by_name.is_some());
assert_eq!(&**user_by_name.unwrap().name, &*name);
assert_eq!(user_by_name.unwrap().name(), &*name);

// User names containing '\0' cannot be used (for now)
let user = get_user_by_name("user\0");
Expand Down
8 changes: 4 additions & 4 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ impl Users for UsersCache {
Vacant(entry) => {
match super::get_user_by_uid(uid) {
Some(user) => {
let newsername = user.name.clone();
let newsername = user.name_arc.clone();
let mut users_backward = self.users.backward.borrow_mut();
users_backward.insert(newsername, Some(uid));

Expand All @@ -161,7 +161,7 @@ impl Users for UsersCache {
Vacant(entry) => {
match super::get_user_by_name(username) {
Some(user) => {
let uid = user.uid;
let uid = user.uid();
let user_arc = Arc::new(user);

let mut users_forward = self.users.forward.borrow_mut();
Expand Down Expand Up @@ -199,7 +199,7 @@ impl Users for UsersCache {

fn get_current_username(&self) -> Option<Arc<String>> {
let uid = self.get_current_uid();
self.get_user_by_uid(uid).map(|u| u.name.clone())
self.get_user_by_uid(uid).map(|u| u.name_arc.clone())
}

fn get_effective_uid(&self) -> uid_t {
Expand All @@ -215,7 +215,7 @@ impl Users for UsersCache {

fn get_effective_username(&self) -> Option<Arc<String>> {
let uid = self.get_effective_uid();
self.get_user_by_uid(uid).map(|u| u.name.clone())
self.get_user_by_uid(uid).map(|u| u.name_arc.clone())
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
//! ```rust
//! use users::{get_user_by_uid, get_current_uid};
//! let user = get_user_by_uid(get_current_uid()).unwrap();
//! println!("Hello, {}!", user.name);
//! println!("Hello, {}!", user.name());
//! ```
//!
//! This code assumes (with `unwrap()`) that the user hasn’t been deleted after
Expand Down Expand Up @@ -68,7 +68,7 @@
//! let mut cache = UsersCache::new();
//! let uid = cache.get_current_uid();
//! let user = cache.get_user_by_uid(uid).unwrap();
//! println!("Hello again, {}!", user.name);
//! println!("Hello again, {}!", user.name());
//! ```
//!
//! This cache is **only additive**: it’s not possible to drop it, or erase
Expand Down
16 changes: 8 additions & 8 deletions src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl MockUsers {

/// Add a user to the users table.
pub fn add_user(&mut self, user: User) -> Option<Arc<User>> {
self.users.insert(user.uid, Arc::new(user))
self.users.insert(user.uid(), Arc::new(user))
}

/// Add a group to the groups table.
Expand All @@ -99,23 +99,23 @@ impl Users for MockUsers {
}

fn get_user_by_name(&self, username: &str) -> Option<Arc<User>> {
self.users.values().find(|u| &*u.name == username).cloned()
self.users.values().find(|u| u.name() == username).cloned()
}

fn get_current_uid(&self) -> uid_t {
self.uid
}

fn get_current_username(&self) -> Option<Arc<String>> {
self.users.get(&self.uid).map(|u| u.name.clone())
self.users.get(&self.uid).map(|u| u.name_arc.clone())
}

fn get_effective_uid(&self) -> uid_t {
self.uid
}

fn get_effective_username(&self) -> Option<Arc<String>> {
self.users.get(&self.uid).map(|u| u.name.clone())
self.users.get(&self.uid).map(|u| u.name_arc.clone())
}
}

Expand Down Expand Up @@ -171,27 +171,27 @@ mod test {
fn uid() {
let mut users = MockUsers::with_current_uid(0);
users.add_user(User::new(1337, "fred", 101));
assert_eq!(Some(Arc::new("fred".into())), users.get_user_by_uid(1337).map(|u| u.name.clone()))
assert_eq!(Some(Arc::new("fred".into())), users.get_user_by_uid(1337).map(|u| u.name_arc.clone()))
}

#[test]
fn username() {
let mut users = MockUsers::with_current_uid(1337);
users.add_user(User::new(1440, "fred", 101));
assert_eq!(Some(1440), users.get_user_by_name("fred").map(|u| u.uid))
assert_eq!(Some(1440), users.get_user_by_name("fred").map(|u| u.uid()))
}

#[test]
fn no_username() {
let mut users = MockUsers::with_current_uid(1337);
users.add_user(User::new(1337, "fred", 101));
assert_eq!(None, users.get_user_by_name("criminy").map(|u| u.uid))
assert_eq!(None, users.get_user_by_name("criminy").map(|u| u.uid()))
}

#[test]
fn no_uid() {
let users = MockUsers::with_current_uid(0);
assert_eq!(None, users.get_user_by_uid(1337).map(|u| u.name.clone()))
assert_eq!(None, users.get_user_by_uid(1337).map(|u| u.name_arc.clone()))
}

#[test]
Expand Down

0 comments on commit fefddc4

Please sign in to comment.