From 467c8ee007c3f3c3eac27970c06baae69527f00c Mon Sep 17 00:00:00 2001 From: Dietrich Date: Mon, 9 Nov 2020 09:56:24 +0100 Subject: [PATCH] linting changes --- src/api/newuser_args.rs | 3 +- src/bin/delete_user.rs | 6 +-- src/bin/read_all.rs | 2 +- src/error.rs | 24 +++++------ src/group/mod.rs | 14 ++----- src/lib.rs | 9 +++++ src/user/gecos_fields.rs | 42 ++++++++++---------- src/user/mod.rs | 18 ++++----- src/user/passwd_fields.rs | 15 ++----- src/user/shadow_fields.rs | 15 ++----- src/userlib/files.rs | 33 +++++++++------- src/userlib/hashes.rs | 3 ++ src/userlib/mod.rs | 83 +++++++++++++++++++-------------------- tests/delete_user_test.rs | 10 ++--- tests/testfiles.rs | 8 ++-- 15 files changed, 142 insertions(+), 143 deletions(-) diff --git a/src/api/newuser_args.rs b/src/api/newuser_args.rs index b4c0c6a..c62f887 100644 --- a/src/api/newuser_args.rs +++ b/src/api/newuser_args.rs @@ -1,3 +1,4 @@ +#![allow(clippy::default_trait_access)] use std::path::PathBuf; #[derive(Debug, Clone, Eq, PartialEq)] @@ -12,7 +13,6 @@ pub enum DeletePrimaryGroup { Keep, DeleteIfEmpty, } - #[derive(Debug, Builder, Eq, PartialEq)] #[builder(public)] #[builder(default)] @@ -23,6 +23,7 @@ pub struct NewUserArgs<'a> { } impl<'a> NewUserArgs<'a> { + #[must_use] pub fn builder() -> NewUserArgsBuilder<'a> { NewUserArgsBuilder::default() } diff --git a/src/bin/delete_user.rs b/src/bin/delete_user.rs index 7a666ff..726b4cd 100644 --- a/src/bin/delete_user.rs +++ b/src/bin/delete_user.rs @@ -2,6 +2,9 @@ use std::path::PathBuf; extern crate adduser; +use adduser::api::UserDBWrite; +use adduser::api::UserRead; + extern crate env_logger; #[allow(unused_imports)] use log::{debug, error, info, trace, warn}; @@ -9,9 +12,6 @@ use log::{debug, error, info, trace, warn}; fn main() { env_logger::init(); - use adduser::api::UserDBWrite; - use adduser::api::UserRead; - let mf = adduser::Files { passwd: Some(PathBuf::from("./passwd")), shadow: Some(PathBuf::from("./shadow")), diff --git a/src/bin/read_all.rs b/src/bin/read_all.rs index 065ed12..a1a0bb6 100644 --- a/src/bin/read_all.rs +++ b/src/bin/read_all.rs @@ -1,4 +1,5 @@ extern crate adduser; +use adduser::api::UserDBRead; fn main() { simplelog::CombinedLogger::init(vec![simplelog::TermLogger::new( @@ -7,7 +8,6 @@ fn main() { simplelog::TerminalMode::Mixed, )]) .unwrap(); - use adduser::api::UserDBRead; let db = adduser::UserDBLocal::load_files(adduser::Files::default()).unwrap(); diff --git a/src/error.rs b/src/error.rs index eec9b9d..015ea58 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,7 @@ use std::error::Error; use std::fmt::{self, Display}; +#[allow(clippy::module_name_repetitions)] #[derive(Debug, PartialEq)] pub enum ParseError { Username, @@ -12,6 +13,7 @@ pub enum ParseError { ShellDir, } +#[allow(clippy::module_name_repetitions)] #[derive(Debug, PartialEq)] pub enum UserLibError { NotFound, @@ -36,8 +38,8 @@ impl PartialEq for MyMessage { impl Display for MyMessage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - MyMessage::Simple(m) => write!(f, "{}", m), - MyMessage::IOError(m, e) => write!(f, "{},{}", m, e), + Self::Simple(m) => write!(f, "{}", m), + Self::IOError(m, e) => write!(f, "{},{}", m, e), } } } @@ -47,7 +49,7 @@ impl Display for UserLibError { match self { Self::NotFound => write!(f, "not found"), Self::ParseError => write!(f, "failed to parse"), - UserLibError::FilesRequired => write!( + Self::FilesRequired => write!( f, "File locking is only possible if some files are specified" ), @@ -63,12 +65,12 @@ impl Display for UserLibError { impl Error for UserLibError { fn source(&self) -> Option<&(dyn Error + 'static)> { match *self { - UserLibError::NotFound - | UserLibError::ParseError - | UserLibError::FilesChanged - | UserLibError::FilesRequired => None, - UserLibError::Message(MyMessage::IOError(_, ref e)) => Some(e), - UserLibError::Message(MyMessage::Simple(_)) => None, + Self::NotFound + | Self::ParseError + | Self::FilesChanged + | Self::FilesRequired + | Self::Message(MyMessage::Simple(_)) => None, + Self::Message(MyMessage::IOError(_, ref e)) => Some(e), } } } @@ -87,13 +89,13 @@ impl From for UserLibError { impl From for UserLibError { fn from(e: std::io::Error) -> Self { - UserLibError::Message(MyMessage::Simple(e.to_string())) + Self::Message(MyMessage::Simple(e.to_string())) } } impl From<(String, std::io::Error)> for UserLibError { fn from((m, e): (String, std::io::Error)) -> Self { - UserLibError::Message(MyMessage::IOError(m, e)) + Self::Message(MyMessage::IOError(m, e)) } } /* diff --git a/src/group/mod.rs b/src/group/mod.rs index 4445922..628fa26 100644 --- a/src/group/mod.rs +++ b/src/group/mod.rs @@ -1,10 +1,3 @@ -#![warn( - clippy::all, -/* clippy::restriction,*/ - clippy::pedantic, - clippy::nursery, - clippy::cargo -)] #![allow(clippy::non_ascii_literal)] use crate::userlib::NewFromString; @@ -57,10 +50,11 @@ pub struct Group { } impl Group { + #[must_use] pub fn remove_in(&self, content: &str) -> String { content .split(&self.source) - .map(|x| x.trim()) + .map(str::trim) .collect::>() .join("\n") } @@ -75,7 +69,7 @@ impl GroupRead for Group { #[must_use] fn get_member_names(&self) -> Option> { let mut r: Vec<&str> = Vec::new(); - for u in self.members.iter() { + for u in &self.members { r.push(&u.username); } Some(r) @@ -128,7 +122,7 @@ impl NewFromString for Group { if elements.len() == 4 { Ok(Self { pos: position, - source: line.clone(), + source: line, groupname: Groupname::try_from(elements.get(0).unwrap().to_string())?, password: crate::Password::Disabled, gid: crate::Gid::try_from(elements.get(2).unwrap().to_string())?, diff --git a/src/lib.rs b/src/lib.rs index 2d6c472..4212420 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,12 @@ +#![warn( + clippy::all, + //clippy::restriction, + clippy::pedantic, + clippy::nursery, + clippy::cargo +)] +//#![allow(clippy::non_ascii_literal)] + #[macro_use] extern crate lazy_static; #[macro_use] diff --git a/src/user/gecos_fields.rs b/src/user/gecos_fields.rs index de74edd..1a8f670 100644 --- a/src/user/gecos_fields.rs +++ b/src/user/gecos_fields.rs @@ -1,3 +1,4 @@ +#![allow(clippy::non_ascii_literal)] use crate::UserLibError; use std::cmp::Eq; use std::convert::TryFrom; @@ -26,19 +27,19 @@ impl Gecos { #[must_use] pub fn get_comment(&self) -> Option<&str> { match &self { - Gecos::Simple { comment, .. } => Some(&comment), - Gecos::Detail { .. } => None, + Self::Simple { comment, .. } => Some(comment), + Self::Detail { .. } => None, } } #[must_use] pub fn get_full_name(&self) -> Option<&str> { match &self { - Gecos::Simple { .. } => None, - Gecos::Detail { full_name, .. } => { + Self::Simple { .. } => None, + Self::Detail { full_name, .. } => { if full_name.is_empty() { None } else { - Some(&full_name) + Some(full_name) } } } @@ -46,12 +47,12 @@ impl Gecos { #[must_use] pub fn get_room(&self) -> Option<&str> { match &self { - Gecos::Simple { .. } => None, - Gecos::Detail { room, .. } => { + Self::Simple { .. } => None, + Self::Detail { room, .. } => { if room.is_empty() { None } else { - Some(&room) + Some(room) } } } @@ -59,12 +60,12 @@ impl Gecos { #[must_use] pub fn get_phone_work(&self) -> Option<&str> { match &self { - Gecos::Simple { .. } => None, - Gecos::Detail { phone_work, .. } => { + Self::Simple { .. } => None, + Self::Detail { phone_work, .. } => { if phone_work.is_empty() { None } else { - Some(&phone_work) + Some(phone_work) } } } @@ -72,12 +73,12 @@ impl Gecos { #[must_use] pub fn get_phone_home(&self) -> Option<&str> { match &self { - Gecos::Simple { .. } => None, - Gecos::Detail { phone_home, .. } => { + Self::Simple { .. } => None, + Self::Detail { phone_home, .. } => { if phone_home.is_empty() { None } else { - Some(&phone_home) + Some(phone_home) } } } @@ -85,8 +86,8 @@ impl Gecos { #[must_use] pub const fn get_other(&self) -> Option<&Vec> { match self { - Gecos::Simple { .. } => None, - Gecos::Detail { other, .. } => match other { + Self::Simple { .. } => None, + Self::Detail { other, .. } => match other { None => None, Some(comments) => Some(comments), }, @@ -97,8 +98,8 @@ impl Gecos { impl Display for Gecos { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self { - Gecos::Simple { comment } => write!(f, "{}", comment), - Gecos::Detail { + Self::Simple { comment } => write!(f, "{}", comment), + Self::Detail { full_name, room, phone_work, @@ -125,7 +126,7 @@ impl TryFrom for Gecos { fn try_from(source: String) -> std::result::Result { let vals: Vec = source.split(',').map(ToString::to_string).collect(); if vals.len() > 3 { - Ok(Gecos::Detail { + Ok(Self::Detail { full_name: vals[0].clone(), room: vals[1].clone(), phone_work: vals[2].clone(), @@ -137,7 +138,7 @@ impl TryFrom for Gecos { }, }) } else if vals.len() == 1 { - Ok(Gecos::Simple { + Ok(Self::Simple { comment: vals.get(0).unwrap().into(), }) } else { @@ -145,7 +146,6 @@ impl TryFrom for Gecos { } } } - #[test] fn test_parse_gecos() { // test if the Gecos field can be parsed and the resulting struct is populated correctly. diff --git a/src/user/mod.rs b/src/user/mod.rs index ccb6621..d2603fd 100644 --- a/src/user/mod.rs +++ b/src/user/mod.rs @@ -24,11 +24,11 @@ pub struct User { } impl User { - pub fn get_shadow(&self) -> Option<&crate::Shadow> { + #[must_use] + pub const fn get_shadow(&self) -> Option<&crate::Shadow> { match self.password { - crate::Password::Encrypted(_) => None, + crate::Password::Encrypted(_) | crate::Password::Disabled => None, crate::Password::Shadow(ref s) => Some(s), - crate::Password::Disabled => None, } } /*fn get_nth_line(content: &str, n: u32) -> (String, u64) { @@ -49,17 +49,16 @@ impl User { trace!("Olduser:\n\t{}\nNewuser\n\t{}", &self.source, &line); (offset, line.len(), line == self.source) }*/ + #[must_use] pub fn remove_in(&self, content: &str) -> String { content .split(&self.source) - .map(|x| x.trim()) + .map(str::trim) .collect::>() .join("\n") } pub fn username(&mut self, name: String) -> &mut Self { - self.username = crate::Username { - username: name.into(), - }; + self.username = crate::Username { username: name }; self } pub fn disable_password(&mut self) -> &mut Self { @@ -131,7 +130,7 @@ impl crate::api::UserRead for User { #[must_use] fn get_password(&self) -> Option<&str> { match &self.password { - crate::Password::Encrypted(crate::EncryptedPassword { password }) => Some(&password), + crate::Password::Encrypted(crate::EncryptedPassword { password }) => Some(password), crate::Password::Shadow(crate::Shadow { ref password, .. }) => Some(&password.password), crate::Password::Disabled => None, } @@ -287,6 +286,7 @@ fn test_new_from_string() { #[test] fn test_parse_passwd() { // Test wether the passwd file can be parsed and recreated without throwing an exception + use std::convert::TryInto; use std::fs::File; use std::io::{prelude::*, BufReader}; let file = File::open("/etc/passwd").unwrap(); @@ -295,7 +295,7 @@ fn test_parse_passwd() { for (n, line) in reader.lines().enumerate() { let lineorig: String = line.unwrap(); let linecopy = lineorig.clone(); - let pass_struc = User::new_from_string(linecopy, n as u32).unwrap(); + let pass_struc = User::new_from_string(linecopy, n.try_into().unwrap()).unwrap(); assert_eq!( // ignoring the numbers of `,` since the implementation does not (yet) reproduce a missing comment field. lineorig, diff --git a/src/user/passwd_fields.rs b/src/user/passwd_fields.rs index 4b81f0a..9e2fb80 100644 --- a/src/user/passwd_fields.rs +++ b/src/user/passwd_fields.rs @@ -1,10 +1,3 @@ -#![warn( - clippy::all, -/* clippy::restriction,*/ - clippy::pedantic, - clippy::nursery, - clippy::cargo -)] #![allow(clippy::non_ascii_literal)] use log::warn; @@ -65,8 +58,7 @@ impl Display for Password { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Encrypted(EncryptedPassword { password }) => write!(f, "{}", password,), - Self::Shadow(_) => write!(f, "x"), - Self::Disabled => write!(f, "x"), + Self::Shadow(_) | Self::Disabled => write!(f, "x"), } } } @@ -85,11 +77,11 @@ impl Display for EncryptedPassword { impl TryFrom for EncryptedPassword { type Error = UserLibError; fn try_from(source: String) -> std::result::Result { - if source == "x" { + /*if source == "x" { //warn!("password from shadow not loaded!") } else { //warn!("Password field has an unexpected value") - }; + };*/ Ok(Self { password: source }) } } @@ -149,6 +141,7 @@ impl Gid { self.gid < 1000 } + #[must_use] pub const fn get_gid(&self) -> u32 { self.gid } diff --git a/src/user/shadow_fields.rs b/src/user/shadow_fields.rs index 71957e6..115e39a 100644 --- a/src/user/shadow_fields.rs +++ b/src/user/shadow_fields.rs @@ -1,14 +1,4 @@ -#![warn( - clippy::all, -/* clippy::restriction,*/ - clippy::pedantic, - clippy::nursery, - clippy::cargo -)] -#![allow(clippy::non_ascii_literal)] - use crate::userlib::NewFromString; -use log::warn; use crate::UserLibError; use std::cmp::Eq; @@ -40,10 +30,11 @@ impl Shadow { pub fn get_password(&self) -> &str { &self.password.password } + #[must_use] pub fn remove_in(&self, content: &str) -> String { content .split(&self.source) - .map(|x| x.trim()) + .map(str::trim) .collect::>() .join("\n") } @@ -108,7 +99,7 @@ impl NewFromString for Shadow { let extra = elements.get(8).unwrap(); Ok(Self { pos: position, - source: line.clone(), + source: line, username: crate::Username::try_from(elements.get(0).unwrap().to_string())?, password: crate::EncryptedPassword::try_from(elements.get(1).unwrap().to_string())?, last_change: date_since_epoch(elements.get(2).unwrap()), diff --git a/src/userlib/files.rs b/src/userlib/files.rs index 83bca9c..a86681d 100644 --- a/src/userlib/files.rs +++ b/src/userlib/files.rs @@ -26,7 +26,8 @@ impl Default for Files { impl Files { /// Check if all the files are defined. Because some operations require the files to be present - pub fn is_virtual(&self) -> bool { + #[must_use] + pub const fn is_virtual(&self) -> bool { !(self.group.is_some() & self.passwd.is_some() & self.shadow.is_some()) } pub fn lock_and_get_passwd(&self) -> Result { @@ -89,7 +90,7 @@ impl LockedFileGuard { Ok(_) => (), Err(e) => return Err(("Could not write (all) users. ".to_owned(), e).into()), }; - let _ = self.file.write("\n".as_bytes()); + let _ = self.file.write(b"\n"); Ok(()) } @@ -155,12 +156,19 @@ impl LockedFileGuard { ); // write the pid into the tempfile { - let mut tempfile = File::create(&*tempfilepath) - .expect(&format!("Failed to open {}", filename.to_str().unwrap())); - match write!(tempfile, "{}", pid) { - Ok(_) => {} - Err(_) => error!("could not write to {}", filename.to_string_lossy()), - }; + let mut tempfile = File::create(&*tempfilepath).unwrap_or_else(|e| { + panic!("Failed to open {} error: {}", filename.to_str().unwrap(), e) + }); + write!(tempfile, "{}", pid).or_else(|e| { + let error_msg = format!( + "could not write to {} error {}", + filename.to_string_lossy(), + e + ); + error!("{}", error_msg); + let err: crate::UserLibError = error_msg.into(); + Err(err) + })?; } // try to make a hardlink from the lockfile to the tempfile @@ -198,12 +206,9 @@ impl LockedFileGuard { } }; let mut content = String::new(); - match lf.read_to_string(&mut content) { - Ok(_) => {} - Err(_) => { - panic!("failed to read the lockfile{}", e); - } - } + lf.read_to_string(&mut content) + .unwrap_or_else(|e| panic!("failed to read the lockfile{}", e)); + let content = content.trim().trim_matches(char::from(0)); let lock_pid = content.parse::(); match lock_pid { diff --git a/src/userlib/hashes.rs b/src/userlib/hashes.rs index b6b648a..1cd4593 100644 --- a/src/userlib/hashes.rs +++ b/src/userlib/hashes.rs @@ -5,11 +5,13 @@ pub struct SourceHash { } impl SourceHash { + #[must_use] pub fn new(src: &str) -> Self { Self { hashvalue: src.to_owned(), } } + #[must_use] pub fn has_changed(&self, new: &str) -> bool { trace!( "Old and new lengths: {}, {}", @@ -27,6 +29,7 @@ pub struct Hashes { } impl Hashes { + #[must_use] pub fn new(passwd: &str, shadow: &str, group: &str) -> Self { Self { passwd: SourceHash::new(passwd), diff --git a/src/userlib/mod.rs b/src/userlib/mod.rs index 92ba289..72f593b 100644 --- a/src/userlib/mod.rs +++ b/src/userlib/mod.rs @@ -1,10 +1,3 @@ -#![warn( - clippy::all, - //clippy::restriction, - clippy::pedantic, - clippy::nursery, - clippy::cargo -)] #![allow(clippy::non_ascii_literal)] pub mod files; @@ -33,11 +26,11 @@ impl UserDBLocal { shadow_content: &str, group_content: &str, ) -> Self { - let shadow_entries: Vec = string_to(&shadow_content); - let mut users = user_vec_to_hashmap(string_to(&passwd_content)); - let groups = string_to(&group_content); + let shadow_entries: Vec = string_to(shadow_content); + let mut users = user_vec_to_hashmap(string_to(passwd_content)); + let groups = string_to(group_content); shadow_to_users(&mut users, shadow_entries); - let res = Self { + Self { source_files: files::Files { passwd: None, group: None, @@ -45,13 +38,11 @@ impl UserDBLocal { }, users, groups, - source_hashes: hashes::Hashes::new(&passwd_content, &shadow_content, &group_content), - }; - res + source_hashes: hashes::Hashes::new(passwd_content, shadow_content, group_content), + } } /// Import the database from a [`Files`] struct - #[must_use] pub fn load_files(files: files::Files) -> Result { // Get the Strings for the files use an inner block to drop references after read. let (my_passwd_lines, my_shadow_lines, my_group_lines) = { @@ -77,10 +68,10 @@ impl UserDBLocal { } fn delete_from_passwd( user: &crate::User, - passwd_file_content: String, + passwd_file_content: &str, locked_p: &mut files::LockedFileGuard, ) -> Result<(), UserLibError> { - let modified_p = user.remove_in(&passwd_file_content); + let modified_p = user.remove_in(passwd_file_content); // write the new content to the file. let ncont = locked_p.replace_contents(modified_p); @@ -92,13 +83,13 @@ impl UserDBLocal { fn delete_from_shadow( user: &crate::User, - shadow_file_content: String, + shadow_file_content: &str, locked_s: &mut files::LockedFileGuard, ) -> Result<(), UserLibError> { let shad = user.get_shadow(); match shad { Some(shadow) => { - let modified_s = shadow.remove_in(&shadow_file_content); + let modified_s = shadow.remove_in(shadow_file_content); let ncont = locked_s.replace_contents(modified_s); match ncont { Ok(_) => Ok(()), @@ -116,10 +107,10 @@ impl UserDBLocal { fn delete_from_group( group: &crate::Group, - group_file_content: String, + group_file_content: &str, locked_g: &mut files::LockedFileGuard, ) -> Result<(), UserLibError> { - let modified_g = group.remove_in(&group_file_content); + let modified_g = group.remove_in(group_file_content); let replace_result = locked_g.replace_contents(modified_g); match replace_result { Ok(_) => Ok(()), @@ -133,15 +124,15 @@ impl UserDBLocal { } fn delete_home(user: &crate::User) -> std::io::Result<()> { - match user.get_home_dir() { - Some(dir) => std::fs::remove_dir_all(dir), - None => { - error!("Failed to remove the home directory! As the user did not have one."); - Err(std::io::Error::new( - std::io::ErrorKind::InvalidInput, - "Failed to remove the home directory! As the user did not have one.", - )) - } + if let Some(dir) = user.get_home_dir() { + std::fs::remove_dir_all(dir) + } else { + let error_msg = "Failed to remove the home directory! As the user did not have one."; + error!("{}", error_msg); + Err(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + error_msg, + )) } } @@ -190,8 +181,8 @@ impl UserDBWrite for UserDBLocal { error!("The source files have changed. Deleting the user could corrupt the userdatabase. Aborting!"); Err(format!("The userdatabase has been changed {}", args.username).into()) } else { - Self::delete_from_passwd(user, passwd_file_content, &mut locked_p)?; - Self::delete_from_shadow(user, shadow_file_content, &mut locked_s)?; + Self::delete_from_passwd(user, &passwd_file_content, &mut locked_p)?; + Self::delete_from_shadow(user, &shadow_file_content, &mut locked_s)?; if args.delete_home == DeleteHome::Delete { Self::delete_home(user)?; } @@ -206,7 +197,7 @@ impl UserDBWrite for UserDBLocal { { UserDBLocal::delete_from_group( group, - group_file_content, + &group_file_content, &mut locked_g, )?; let _gres = self.groups.remove(id); @@ -297,9 +288,9 @@ impl UserDBRead for UserDBLocal { fn get_user_by_id(&self, uid: u32) -> Option<&crate::User> { // could probably be more efficient - on the other hand its no problem to loop a thousand users. - for (_, user) in self.users.iter() { + for user in self.users.values() { if user.get_uid() == uid { - return Some(&user); + return Some(user); } } None @@ -310,7 +301,7 @@ impl UserDBRead for UserDBLocal { } fn get_group_by_name(&self, name: &str) -> Option<&crate::Group> { - for group in self.groups.iter() { + for group in &self.groups { if group.get_groupname()? == name { return Some(group); } @@ -319,7 +310,7 @@ impl UserDBRead for UserDBLocal { } fn get_group_by_id(&self, id: u32) -> Option<&crate::Group> { - for group in self.groups.iter() { + for group in &self.groups { if group.get_gid()? == id { return Some(group); } @@ -376,7 +367,7 @@ fn shadow_to_users( for pass in shadow { let user = users .get_mut(pass.get_username()) - .expect(&format!("the user {} does not exist", pass.get_username())); + .unwrap_or_else(|| panic!("the user {} does not exist", pass.get_username())); user.password = crate::Password::Shadow(pass); } users @@ -397,7 +388,7 @@ fn user_vec_to_hashmap(users: Vec) -> HashMap .collect() } -/// Try to parse a String into some Object +/// Try to parse a String into some Object. /// /// # Errors /// if the parsing failed a [`UserLibError::Message`](crate::userlib_error::UserLibError::Message) is returned containing a more detailed error message. @@ -412,12 +403,20 @@ fn string_to(source: &str) -> Vec where T: NewFromString, { + use std::convert::TryInto; source .lines() .enumerate() .filter_map(|(n, line)| { if line.len() > 5 { - Some(T::new_from_string(line.to_owned(), n as u32).expect("failed to read lines")) + Some( + T::new_from_string( + line.to_owned(), + n.try_into() + .unwrap_or_else(|e| panic!("Failed to convert usize to u32 {}", e)), + ) + .expect("failed to read lines"), + ) } else { None } @@ -484,10 +483,10 @@ fn test_user_db_write_implementation() { assert_eq!(data.get_all_users().len(), 1); assert!(data - .delete_user(NewUserArgs::builder().username(&user).build().unwrap()) + .delete_user(NewUserArgs::builder().username(user).build().unwrap()) .is_ok()); assert!(data - .delete_user(NewUserArgs::builder().username(&user).build().unwrap()) + .delete_user(NewUserArgs::builder().username(user).build().unwrap()) .is_err()); assert_eq!(data.get_all_users().len(), 0); } diff --git a/tests/delete_user_test.rs b/tests/delete_user_test.rs index 678a8de..462b0f0 100644 --- a/tests/delete_user_test.rs +++ b/tests/delete_user_test.rs @@ -17,8 +17,8 @@ fn test_test() { let mf = adduser::Files { passwd: Some(p.path.clone()), - shadow: Some(s.path.clone()), - group: Some(g.path.clone()), + shadow: Some(s.path), + group: Some(g.path), }; let mut db = adduser::UserDBLocal::load_files(mf).unwrap(); @@ -32,9 +32,9 @@ fn test_test() { ); let pf2 = fs::read_to_string(&p.path).unwrap(); assert_eq!(user_res.unwrap().get_username().unwrap(), "teste"); - let pfl = pf.lines(); - let pfl2 = pf2.lines(); - for (l1, l2) in pfl.zip(pfl2) { + let pflines = pf.lines(); + let pflines2 = pf2.lines(); + for (l1, l2) in pflines.zip(pflines2) { if l1 != l2 { dbg!(l1, l2); assert!(l1.starts_with("teste")); diff --git a/tests/testfiles.rs b/tests/testfiles.rs index 07b4332..a5e4454 100644 --- a/tests/testfiles.rs +++ b/tests/testfiles.rs @@ -12,6 +12,7 @@ pub struct Fixture { } impl Fixture { + #[must_use] pub fn blank(fixture_filename: &str) -> Self { // First, figure out the right file in `tests/fixtures/`: let root_dir = &env::var("CARGO_MANIFEST_DIR").expect("$CARGO_MANIFEST_DIR"); @@ -24,14 +25,15 @@ impl Fixture { let mut path = PathBuf::from(&tempdir.path()); path.push(&fixture_filename); - Fixture { + Self { _tempdir: tempdir, source, path, } } + #[must_use] pub fn copy(fixture_filename: &str) -> Self { - let fixture = Fixture::blank(fixture_filename); + let fixture = Self::blank(fixture_filename); fs::copy(&fixture.source, &fixture.path).unwrap(); fixture } @@ -41,6 +43,6 @@ impl Deref for Fixture { type Target = Path; fn deref(&self) -> &Self::Target { - self.path.deref() + &self.path } }