diff --git a/Modules/Task/src/Manager.rs b/Modules/Task/src/Manager.rs index 28d80c3..90f2def 100644 --- a/Modules/Task/src/Manager.rs +++ b/Modules/Task/src/Manager.rs @@ -8,7 +8,7 @@ use std::{ sync::{OnceLock, RwLock}, time::Duration, }; -use Users::{Root_user_identifier, User_identifier_type}; +use Users::User_identifier_type; /// Internal representation of a task. struct Task_internal_type { @@ -68,7 +68,7 @@ impl Manager_type { let Task_internal = Task_internal_type { Main_thread: Thread_wrapper_type::Get_current(), Parent: Task_identifier, - Owner: Root_user_identifier, + Owner: User_identifier_type::Root, Environment_variables: vec![], }; @@ -102,7 +102,7 @@ impl Manager_type { let Task_internal = Task_internal_type { Main_thread: Thread_wrapper_type::Get_current(), Parent: Self::Root_task_identifier, - Owner: Root_user_identifier, + Owner: User_identifier_type::Root, Environment_variables: vec![], }; @@ -558,7 +558,7 @@ mod Tests { } fn Test_get_owner(Manager: &Manager_type) { - let User_identifier = 123; // Assuming User_identifier_type is i32 for example + let User_identifier = User_identifier_type::New(123); // Assuming User_identifier_type is i32 for example let Task = Manager.Get_current_task_identifier().unwrap(); @@ -590,7 +590,7 @@ mod Tests { } fn Test_task_owner_inheritance(Manager: &Manager_type) { - let User_identifier = 123; // Assuming User_identifier_type is i32 for example + let User_identifier = User_identifier_type::New(123); // Assuming User_identifier_type is i32 for example let Task = Manager.Get_current_task_identifier().unwrap(); let _ = Manager @@ -611,12 +611,14 @@ mod Tests { }) .unwrap(); + let User_identifier = User_identifier_type::New(6969); // Assuming User_identifier_type is i32 for example + // - Overwrite owner let _ = Get_instance() - .New_task(Task, Some(6969), "Task 3", None, move || { + .New_task(Task, Some(User_identifier), "Task 3", None, move || { let Task = Get_instance().Get_current_task_identifier().unwrap(); - assert_eq!(Get_instance().Get_owner(Task).unwrap(), 6969); + assert_eq!(Get_instance().Get_owner(Task).unwrap(), User_identifier); assert_eq!(Get_instance().Get_task_name(Task).unwrap(), "Task 3"); }) .unwrap(); diff --git a/Modules/Users/src/Identifiers.rs b/Modules/Users/src/Identifiers.rs new file mode 100644 index 0000000..75b2f6b --- /dev/null +++ b/Modules/Users/src/Identifiers.rs @@ -0,0 +1,89 @@ +use std::ops::{Add, AddAssign}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] +#[repr(transparent)] +pub struct User_identifier_type(u16); + +impl User_identifier_type { + pub const Root: Self = Self::New(0); + + pub const Minimum: Self = Self::New(1); + pub const Maximum: Self = Self::New(u16::MAX); + + pub const fn New(Identifier: u16) -> Self { + Self(Identifier) + } + + pub const fn Into_inner(self) -> u16 { + self.0 + } +} + +impl AddAssign for User_identifier_type { + fn add_assign(&mut self, Other: u16) { + self.0 += Other; + } +} + +impl Add for User_identifier_type { + type Output = Self; + + fn add(self, Other: u16) -> Self { + Self::New(self.0 + Other) + } +} + +impl From for User_identifier_type { + fn from(Value: u16) -> Self { + User_identifier_type::New(Value) + } +} +impl From for u16 { + fn from(Value: User_identifier_type) -> Self { + Value.Into_inner() + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] +#[repr(transparent)] +pub struct Group_identifier_type(u16); + +impl Group_identifier_type { + pub const Root: Self = Self::New(0); + + pub const Minimum: Self = Self::New(1); + pub const Maximum: Self = Self::New(u16::MAX); + + pub const fn New(Identifier: u16) -> Self { + Self(Identifier) + } + + pub const fn Into_inner(self) -> u16 { + self.0 + } +} + +impl From for Group_identifier_type { + fn from(Value: u16) -> Self { + Group_identifier_type::New(Value) + } +} +impl From for u16 { + fn from(Value: Group_identifier_type) -> Self { + Value.Into_inner() + } +} + +impl AddAssign for Group_identifier_type { + fn add_assign(&mut self, Other: u16) { + self.0 += Other; + } +} + +impl Add for Group_identifier_type { + type Output = Self; + + fn add(self, Other: u16) -> Self { + Self::New(self.0 + Other) + } +} diff --git a/Modules/Users/src/Manager.rs b/Modules/Users/src/Manager.rs index 2d3ebfe..f3a9475 100644 --- a/Modules/Users/src/Manager.rs +++ b/Modules/Users/src/Manager.rs @@ -52,7 +52,7 @@ impl Manager_type { fn New() -> Self { let mut Groups = BTreeMap::new(); Groups.insert( - Root_group_identifier, + Group_identifier_type::Root, Internal_group_type { Name: "root".to_string(), Users: BTreeSet::new(), @@ -61,26 +61,46 @@ impl Manager_type { let mut Users = BTreeMap::new(); Users.insert( - crate::Root_user_identifier, + User_identifier_type::Root, Internal_user_type { Name: "root".to_string(), - Primary_group: Root_group_identifier, + Primary_group: Group_identifier_type::Root, }, ); Self(RwLock::new(Internal_manager_type { Users, Groups })) } - fn Get_new_group_identifier(&self) -> Option { - let Inner = self.0.read().ok()?; + fn Get_new_group_identifier( + Groups: &BTreeMap, + ) -> Result_type { + let mut Identifier = Group_identifier_type::Minimum; + + while Groups.contains_key(&Identifier) { + Identifier += 1; - (0..Group_identifier_type::MAX).find(|Identifier| !Inner.Groups.contains_key(Identifier)) + if Identifier == Group_identifier_type::Maximum { + return Err(Error_type::Too_many_groups); + } + } + + Ok(Identifier) } - fn Get_new_user_identifier(&self) -> Option { - let Inner = self.0.read().ok()?; + fn Get_new_user_identifier( + Users: &BTreeMap, + ) -> Result_type { + let mut Identifier = User_identifier_type::Minimum; + + while Users.contains_key(&Identifier) { + Identifier += 1; - (0..User_identifier_type::MAX).find(|Identifier| !Inner.Users.contains_key(Identifier)) + if Identifier == User_identifier_type::Maximum { + return Err(Error_type::Too_many_users); + } + } + + Ok(Identifier) } pub fn Create_user( @@ -88,27 +108,30 @@ impl Manager_type { Name: &str, Primary_group: Group_identifier_type, ) -> Result_type { - let Identifier = match self.Get_new_user_identifier() { - Some(Identifier) => Identifier, - None => return Err(Error_type::Too_many_users), - }; + let mut Inner = self.0.write()?; + + let Identifier = Self::Get_new_user_identifier(&Inner.Users)?; let User = Internal_user_type { Name: Name.to_string(), Primary_group, }; - if self.Exists_user(Identifier)? { - return Err(Error_type::Duplicate_user_identifier); - } - - let mut Inner = self.0.write().unwrap(); - + // - Add user to the users map if Inner.Users.insert(Identifier, User).is_some() { return Err(Error_type::Duplicate_user_identifier); // Shouldn't happen } - self.Add_to_group(Identifier, Primary_group)?; + // - Add user to the primary group + if !Inner + .Groups + .get_mut(&Primary_group) + .ok_or(Error_type::Invalid_group_identifier)? + .Users + .insert(Identifier) + { + return Err(Error_type::Duplicate_user_identifier); // Shouldn't happen + } Ok(Identifier) } @@ -118,11 +141,15 @@ impl Manager_type { Name: &str, Identifier: Option, ) -> Result_type { - let Identifier = match Identifier { - Some(Identifier) => Identifier, - None => self - .Get_new_group_identifier() - .ok_or(Error_type::Too_many_groups)?, + let mut Inner = self.0.write()?; + + let Identifier = if let Some(Identifier) = Identifier { + if Inner.Groups.contains_key(&Identifier) { + return Err(Error_type::Duplicate_group_identifier); + } + Identifier + } else { + Self::Get_new_group_identifier(&Inner.Groups)? }; let Group = Internal_group_type { @@ -130,12 +157,6 @@ impl Manager_type { Users: BTreeSet::new(), }; - if self.Exists_group(Identifier)? { - return Err(Error_type::Duplicate_group_identifier); - } - - let mut Inner = self.0.write().unwrap(); - if Inner.Groups.insert(Identifier, Group).is_some() { return Err(Error_type::Duplicate_group_identifier); // Shouldn't happen } @@ -143,7 +164,7 @@ impl Manager_type { } pub fn Is_root(Identifier: User_identifier_type) -> bool { - crate::Root_user_identifier == Identifier + User_identifier_type::Root == Identifier } pub fn Is_in_group( @@ -163,20 +184,10 @@ impl Manager_type { pub fn Get_user_groups( &self, Identifier: User_identifier_type, - ) -> Option> { - let Inner = self.0.read().unwrap(); + ) -> Result_type> { + let Inner = self.0.read()?; - let mut Size = 1; - - Size += Inner - .Groups - .iter() - .filter(|(_, Group)| Group.Users.contains(&Identifier)) - .count(); - - let mut User_groups: Vec = Vec::with_capacity(Size); - - User_groups.push(Inner.Users.get(&Identifier).unwrap().Primary_group); + let mut User_groups: BTreeSet = BTreeSet::new(); User_groups.extend( Inner @@ -186,7 +197,7 @@ impl Manager_type { .map(|(Identifier, _)| *Identifier), ); - Some(User_groups) + Ok(User_groups) } pub fn Exists_group(&self, Identifier: Group_identifier_type) -> Result_type { @@ -271,17 +282,11 @@ impl Manager_type { mod Tests { use super::*; - #[test] - fn New() { - let Manager = Manager_type::New(); - assert!(Manager.0.read().unwrap().Groups.is_empty()); - } - #[test] fn Create_user() { let Manager = Manager_type::New(); let User_name = "Alice"; - let Result = Manager.Create_user(User_name, Root_group_identifier); + let Result = Manager.Create_user(User_name, Group_identifier_type::Root); assert!(Result.is_ok()); let User_id = Result.unwrap(); assert!(Manager.Exists_user(User_id).unwrap()); @@ -299,7 +304,7 @@ mod Tests { #[test] fn Is_root() { - let Root_id = crate::Root_user_identifier; + let Root_id = User_identifier_type::Root; assert!(Manager_type::Is_root(Root_id)); } @@ -308,7 +313,7 @@ mod Tests { let Manager = Manager_type::New(); let User_name = "Bob"; let User_id = Manager - .Create_user(User_name, Root_group_identifier) + .Create_user(User_name, Group_identifier_type::Root) .unwrap(); let Group_name = "Admins"; let Group_id = Manager.Create_group(Group_name, None).unwrap(); @@ -322,7 +327,7 @@ mod Tests { let User_name = "Charlie"; let User_id = Manager - .Create_user(User_name, Root_group_identifier) + .Create_user(User_name, Group_identifier_type::Root) .unwrap(); let Group_name1 = "TeamA"; let Group_id1 = Manager.Create_group(Group_name1, None).unwrap(); @@ -331,8 +336,13 @@ mod Tests { Manager.Add_to_group(User_id, Group_id1).unwrap(); Manager.Add_to_group(User_id, Group_id2).unwrap(); let Groups = Manager.Get_user_groups(User_id).unwrap(); - assert_eq!(Groups.len(), 2); - assert!(Groups.contains(&Group_id1) && Groups.contains(&Group_id2)); + println!("{:?}", Groups); + assert_eq!(Groups.len(), 3); + assert!( + Groups.contains(&Group_id1) + && Groups.contains(&Group_id2) + && Groups.contains(&Group_identifier_type::Root) + ); } #[test] @@ -349,7 +359,7 @@ mod Tests { let Manager = Manager_type::New(); let User_name = "Dave"; let User_id = Manager - .Create_user(User_name, Root_group_identifier) + .Create_user(User_name, Group_identifier_type::Root) .unwrap(); let Group_name = "Engineers"; let Group_id = Manager.Create_group(Group_name, None).unwrap(); @@ -364,7 +374,7 @@ mod Tests { let Manager = Manager_type::New(); let User_name = "Eve"; let User_id = Manager - .Create_user(User_name, Root_group_identifier) + .Create_user(User_name, Group_identifier_type::Root) .unwrap(); let Retrieved_name = Manager.Get_user_name(User_id).unwrap(); assert_eq!(User_name, Retrieved_name); diff --git a/Modules/Users/src/lib.rs b/Modules/Users/src/lib.rs index d53a9c7..3ef5683 100644 --- a/Modules/Users/src/lib.rs +++ b/Modules/Users/src/lib.rs @@ -2,13 +2,10 @@ #![allow(non_snake_case)] #![allow(non_upper_case_globals)] -pub type User_identifier_type = u16; -pub type Group_identifier_type = u16; -pub const Root_user_identifier: User_identifier_type = 0; -pub const Root_group_identifier: Group_identifier_type = 0; - +mod Error; +mod Identifiers; mod Manager; -pub use Manager::*; -mod Error; pub use Error::*; +pub use Identifiers::*; +pub use Manager::*;