Skip to content

Commit

Permalink
Add permissions data structures to file system
Browse files Browse the repository at this point in the history
  • Loading branch information
AlixANNERAUD committed Jun 27, 2024
1 parent ce25046 commit 9378072
Show file tree
Hide file tree
Showing 2 changed files with 261 additions and 0 deletions.
259 changes: 259 additions & 0 deletions Modules/File_system/src/Generics/Fundamentals/Permission.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Permissions_type(u16);

impl Permissions_type {
/// Creates a new permission.
pub fn New(User: &Permission_type, Group: &Permission_type, Others: &Permission_type) -> Self {
Self(0).Set_user(User).Set_group(Group).Set_others(Others)
}

/// Creates a new permission with full access (read, write, execute) for all (user, group, others).
pub fn New_all_full() -> Self {
Self::New(
&Permission_type::New_full(),
&Permission_type::New_full(),
&Permission_type::New_full(),
)
}

/// Creates a new permission with full access (read, write, execute) for user. No access for group and others.
pub fn New_user_full() -> Self {
Self::New(
&Permission_type::New_full(),
&Permission_type::New_none(),
&Permission_type::New_none(),
)
}

/// Creates a new permission with read write access for user. No access for group and others.
pub fn New_user_read_write() -> Self {
Self::New(
&Permission_type::New_read_write(),
&Permission_type::New_none(),
&Permission_type::New_none(),
)
}

/// Creates a new permission with read access for user. No access for group and others.
pub fn New_standard_directory() -> Self {
Self::New(
&Permission_type::New_full(),
&Permission_type::New_write(),
&Permission_type::New_execute(),
)
}

/// Creates a new permission with read access for user. No access for group and others.
pub fn New_standard_file() -> Self {
Self::New(
&Permission_type::New_full(),
&Permission_type::New_read(),
&Permission_type::New_none(),
)
}

/// Sets the permission for the user.
pub fn Set_user(mut self, User: &Permission_type) -> Self {
self.0 = (self.0 & 0o077) | (User.To_unix() as u16) << 6;
self
}

/// Sets the permission for the group.
pub fn Set_group(mut self, Group: &Permission_type) -> Self {
self.0 = (self.0 & 0o707) | (Group.To_unix() as u16) << 3;
self
}

/// Sets the permission for others.
pub fn Set_others(mut self, Others: &Permission_type) -> Self {
self.0 = (self.0 & 0o770) | Others.To_unix() as u16;
self
}

/// Gets the permission for the user.
pub fn Get_user(&self) -> Permission_type {
Permission_type::From_unix((self.0 >> 6) as u8).unwrap()
}

/// Gets the permission for the group.
pub fn Get_group(&self) -> Permission_type {
Permission_type::From_unix(((self.0 >> 3) & 0b111) as u8).unwrap()
}

/// Gets the permission for others.
pub fn Get_others(&self) -> Permission_type {
Permission_type::From_unix((self.0 & 0b111) as u8).unwrap()
}

/// Converts the permission to a Unix permission.
pub fn From_unix(Unix: u16) -> Option<Self> {
if Unix > 0o777 {
return None;
}

Some(Self(Unix))
}

/// Converts the permission to a Unix permission.
pub fn To_unix(&self) -> u16 {
self.0
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Permission_type(u8);

impl Permission_type {
/// Creates a new permission.
pub fn New(Read: bool, Write: bool, Execute: bool) -> Self {
Self((Read as u8) << 2 | (Write as u8) << 1 | Execute as u8)
}

/// Creates a new permission with read access (equivalent to Unix permission 4).
pub fn New_read() -> Self {
Self::New(true, false, false)
}

/// Creates a new permission with write access (equivalent to Unix permission 2).
pub fn New_write() -> Self {
Self::New(false, true, false)
}

/// Creates a new permission with execute access (equivalent to Unix permission 1).
pub fn New_execute() -> Self {
Self::New(false, false, true)
}

/// Creates a new permission with full access (equivalent to Unix permission 7).
pub fn New_full() -> Self {
Self::New(true, true, true)
}

/// Creates a new permission with no access (equivalent to Unix permission 0).
pub fn New_read_write() -> Self {
Self::New(true, true, false)
}

/// Creates a new permission with no access (equivalent to Unix permission 0).
pub fn New_none() -> Self {
Self::New(false, false, false)
}

/// Sets the read permission.
pub fn Set_read(mut self, Read: bool) -> Self {
self.0 = (self.0 & 0b011) | (Read as u8) << 2;
self
}

/// Sets the write permission.
pub fn Set_write(mut self, Write: bool) -> Self {
self.0 = (self.0 & 0b101) | (Write as u8) << 1;
self
}

/// Sets the execute permission.
pub fn Set_execute(mut self, Execute: bool) -> Self {
self.0 = (self.0 & 0b110) | Execute as u8;
self
}

/// Gets the read permission.
pub fn Get_read(&self) -> bool {
self.0 & 0b100 != 0
}

/// Gets the write permission.
pub fn Get_write(&self) -> bool {
self.0 & 0b010 != 0
}

/// Gets the execute permission.
pub fn Get_execute(&self) -> bool {
self.0 & 0b001 != 0
}

/// Converts the permission to a Unix permission.
pub fn To_unix(&self) -> u8 {
self.0
}

/// Creates a permission from a Unix permission.
pub fn From_unix(Unix: u8) -> Option<Self> {
if Unix > 0b111 {
return None;
}

Some(Self(Unix))
}
}

#[cfg(test)]
mod Tests {
use super::*;

#[test]
fn Test_new_permissions() {
let user = Permission_type::New(true, false, false); // Read only
let group = Permission_type::New(false, true, false); // Write only
let others = Permission_type::New(false, false, true); // Execute only
let permissions = Permissions_type::New(&user, &group, &others);
assert_eq!(permissions.0, 0b100_010_001);
}

#[test]
fn Test_new_permission() {
let permissions = Permissions_type::New_all_full();
assert_eq!(permissions.0, 0b111_111_111);

let permissions = Permissions_type::New_user_full();
assert_eq!(permissions.0, 0b111_000_000);

let permissions = Permissions_type::New_user_read_write();
assert_eq!(permissions.0, 0b110_000_000);
}

#[test]
fn Test_permission_type_to_unix() {
let read = Permission_type::New_read();
assert_eq!(read.To_unix(), 4);
let write = Permission_type::New_write();
assert_eq!(write.To_unix(), 2);
let execute = Permission_type::New_execute();
assert_eq!(execute.To_unix(), 1);
let full = Permission_type::New_full();
assert_eq!(full.To_unix(), 7);
let none = Permission_type::New_none();
assert_eq!(none.To_unix(), 0);
}

#[test]
fn Test_permission_type_from_unix() {
let Read = Permission_type::From_unix(4).unwrap();
assert!(Read.Get_read() && !Read.Get_write() && !Read.Get_execute());
let Write = Permission_type::From_unix(2).unwrap();
assert!(!Write.Get_read() && Write.Get_write() && !Write.Get_execute());
let Execute = Permission_type::From_unix(1).unwrap();
assert!(!Execute.Get_read() && !Execute.Get_write() && Execute.Get_execute());
let Full = Permission_type::From_unix(7).unwrap();
assert!(Full.Get_read() && Full.Get_write() && Full.Get_execute());
let No = Permission_type::From_unix(0).unwrap();
assert!(!No.Get_read() && !No.Get_write() && !No.Get_execute());
}

#[test]
fn Test_permissions_type_from_unix() {
let Permissions = Permissions_type::From_unix(0b101_101_101).unwrap();
assert_eq!(Permissions.Get_user().To_unix(), 5);
assert_eq!(Permissions.Get_group().To_unix(), 5);
assert_eq!(Permissions.Get_others().To_unix(), 5);
}

#[test]
fn Test_permissions_type_to_unix() {
let User = Permission_type::New(true, false, true); // Read and execute
let Group = Permission_type::New(true, true, false); // Read and write
let Others = Permission_type::New(false, true, true); // Write and execute
let Permissions = Permissions_type::New(&User, &Group, &Others);
assert_eq!(Permissions.To_unix(), 0b101_110_011);
}
}
2 changes: 2 additions & 0 deletions Modules/File_system/src/Generics/Fundamentals/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
mod Flags;
mod Permission;
pub use Flags::*;
pub use Path::*;
pub use Permission::*;
use Shared::Discriminant_trait;

#[derive(Default, PartialOrd, PartialEq, Eq, Ord, Clone, Copy, Debug)]
Expand Down

0 comments on commit 9378072

Please sign in to comment.