use rand::{thread_rng, RngCore};
use crate::abstractions::{Serializable, SerializationInfo, ID_SIZE};
#[derive(Debug, PartialEq, Eq)]
pub struct BucketPermissions {
pub pub_read: bool, pub pub_write: bool, pub pub_append: bool, pub priv_write: bool, pub priv_append: bool, pub delete_bucket: bool, }
impl Default for BucketPermissions {
fn default() -> Self {
Self {
pub_read: true,
pub_write: false,
pub_append: false,
priv_write: true,
priv_append: false,
delete_bucket: false,
}
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct BucketId {
data: [u8; ID_SIZE],
}
impl BucketId {
pub fn new(lifetime: u8) -> Self {
let mut bytes = [0u8; 16];
thread_rng().fill_bytes(&mut bytes);
let mut res = Self { data: bytes };
res.set_permissions(BucketPermissions::default());
res.set_lifetime(lifetime);
res
}
pub fn lifetime(&self) -> u8 {
self.data[14]
}
pub fn permissions(&self) -> BucketPermissions {
BucketPermissions {
pub_read: self.data[15] & 4 != 0,
pub_write: self.data[15] & 8 != 0,
pub_append: self.data[15] & 16 != 0,
priv_write: self.data[15] & 32 != 0,
priv_append: self.data[15] & 64 != 0,
delete_bucket: self.data[15] & 128 != 0,
}
}
pub fn set_lifetime(&mut self, lifetime: u8) {
self.data[14] = lifetime;
}
pub fn set_permissions(&mut self, permissions: BucketPermissions) {
let mut set_bits: u8 = 0b00000000;
let mut reset_bits: u8 = 0b11111111;
if permissions.pub_read {
set_bits += 4
} else {
reset_bits -= 4
};
if permissions.pub_write {
set_bits += 8
} else {
reset_bits -= 8
};
if permissions.pub_append {
set_bits += 16
} else {
reset_bits -= 16
};
if permissions.priv_write {
set_bits += 32
} else {
reset_bits -= 32
};
if permissions.priv_append {
set_bits += 64
} else {
reset_bits -= 64
};
if permissions.delete_bucket {
set_bits += 128
} else {
reset_bits -= 128
};
let mut permissions = self.data[15];
permissions |= set_bits;
permissions &= reset_bits;
self.data[15] = permissions;
}
}
impl Serializable for BucketId {
fn size(&self) -> usize {
ID_SIZE
}
fn get_bytes(&self) -> Vec<u8> {
self.data.to_vec()
}
fn from_bytes(
data: &[u8],
_: Option<SerializationInfo>,
) -> Result<Self, crate::abstractions::SerializationError>
where
Self: Sized,
{
Ok(BucketId {
data: data.try_into().unwrap(),
})
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn can_create_bucket_id() {
let bucket_id = BucketId::new(0);
assert_eq!(0, bucket_id.lifetime());
assert_eq!(BucketPermissions::default(), bucket_id.permissions());
}
#[test]
fn can_set_bucket_permissions_and_lifetime() {
let bytes = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 255];
let mut id = BucketId::from_bytes(bytes, None).unwrap();
assert_eq!(
BucketPermissions {
pub_read: true,
pub_write: true,
pub_append: true,
priv_write: true,
priv_append: true,
delete_bucket: true
},
id.permissions()
);
assert_eq!(0b11111111, id.data[15]);
assert_eq!("10111111", &format!("{:08b}", 255 - 64));
assert_eq!("00111111", &format!("{:08b}", 255 - 64 - 128));
id.set_permissions(BucketPermissions {
pub_read: true,
pub_write: false,
pub_append: true,
priv_write: false,
priv_append: false,
delete_bucket: true,
});
assert_eq!(
BucketPermissions {
pub_read: true,
pub_write: false,
pub_append: true,
priv_write: false,
priv_append: false,
delete_bucket: true
},
id.permissions()
);
assert_eq!(0b10010111, id.data[15]);
assert_eq!(25, id.lifetime());
id.set_lifetime(253);
assert_eq!(253, id.lifetime());
}
}