From 070c1803030a2c913f8107f37bc7c60fa0310d16 Mon Sep 17 00:00:00 2001 From: Avril Date: Thu, 19 Nov 2020 17:35:06 +0000 Subject: [PATCH] change mb64 a little --- src/conv.rs | 6 ++- src/ext.rs | 19 +++++++ src/server/user.rs | 131 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 140 insertions(+), 16 deletions(-) diff --git a/src/conv.rs b/src/conv.rs index febf156..dafbae1 100644 --- a/src/conv.rs +++ b/src/conv.rs @@ -11,13 +11,16 @@ use regex::{ Regex, }; +//TODO: Mayb use base65536 for URL stuffs? idk.. + const BASE64_VALIDATE_RE_STR: &'static str = r#"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"#; -const MOD_BASE64_VALIDATE_RE_STR: &'static str = r#"^(?:[-A-Za-z0-9_]{4})*(?:[-_A-Za-z0-9]{2}==|[-_A-Za-z0-9]{3}=)?$"#; +const MOD_BASE64_VALIDATE_RE_STR: &'static str = r#"^(?:[-A-Za-z0-9_]{4})*(?:[-_A-Za-z0-9]{2}~~|[-_A-Za-z0-9]{3}~)?$"#; lazy_static!{ static ref BASE64_CONV_TABLE: smallmap::Map = smallmap![ {'/' => '_'}, {'+' => '-'}, + {'=' => '~'}, ]; static ref BASE64_CONV_TABLE_REV: smallmap::Map = BASE64_CONV_TABLE.clone().reverse(); @@ -25,6 +28,7 @@ lazy_static!{ static ref MOD_BASE64_VALIDATE_REGEX: Regex = Regex::new(MOD_BASE64_VALIDATE_RE_STR).expect("Failed to compile modified base64 validation regex"); } +/// An error in base64 or modified base64 encoding/decoding. #[derive(Debug)] pub struct Base64Error(T); diff --git a/src/ext.rs b/src/ext.rs index 1e23ae0..c7fa93c 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -177,3 +177,22 @@ pub type GenericID = uuid::Uuid; } } } + +/// Expands to `unreachable_unchecked` in non-debug builds. +/// +/// # Safety +/// You must make 100% sure this code path will never be entered, or it will cause undefined behaviour in release builds. +#[macro_export] macro_rules! debug_unreachable { + () => { + if cfg!(debug_assertions) { + #[cold] unreachable!() + } else { + unsafe { ::std::hint::unreachable_unchecked() } + } + }; +} + +fn a() -> ! +{ + debug_unreachable!() +} diff --git a/src/server/user.rs b/src/server/user.rs index 58ea4e6..8801fae 100644 --- a/src/server/user.rs +++ b/src/server/user.rs @@ -2,6 +2,7 @@ use super::*; use std::collections::HashMap; use std::borrow::Cow; +use std::ops::Deref; use bitflags::bitflags; @@ -28,6 +29,101 @@ pub struct User groups: Vec, } +/// A reference to a user in a userspace from their ID. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct UserRef<'a>(UserID, &'a Userspace); + +impl<'a> UserRef<'a> +{ + /// The ID of this user reference + #[inline] pub fn id(&self) -> &UserID + { + &self.0 + } + + /// The userspace of this user + #[inline] pub fn space(&self) -> &Userspace + { + self.1 + } + + /// # Note + /// This is for testing purposes only, and should never return `None`. + #[inline(always)] fn try_user(&self) -> Option<&'a User> + { + self.1.users.get(&self.0) + } + + /// The user this ID is referring to + #[inline] pub fn user(&self) -> &User + { + self.try_user().unwrap() + } + + /// Consume into a reference to the user with the lifetime of the `Userspace` containing it. + #[inline] pub fn into_user(self) -> &'a User + { + self.try_user().unwrap() + } +} + +impl<'a> Deref for UserRef<'a> +{ + type Target = User; + fn deref(&self) -> &Self::Target { + self.user() + } +} + +/// A reference to a group in a userspace from their group ID. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GroupRef<'a>(GroupID, &'a Userspace); + +impl<'a> GroupRef<'a> +{ + /// The ID of this group reference + #[inline] pub fn id(&self) -> &GroupID + { + &self.0 + } + + /// The userspace of this group ref + #[inline] pub fn space(&self) -> &Userspace + { + self.1 + } + + /// # Note + /// This is for testing purposes only, and should never return `None`. + #[inline(always)] fn try_group(&self) -> Option<&'a Group> + { + self.1.groups.get(&self.0) + } + + /// The group this ID is referring to + #[inline] pub fn group(&self) -> &Group + { + self.try_group().unwrap() + } + + /// Consume into a reference to the group with the lifetime of the `Userspace` containing it. + #[inline] pub fn into_group(self) -> &'a Group + { + self.try_group().unwrap() + } +} + +impl<'a> Deref for GroupRef<'a> +{ + type Target = Group; + fn deref(&self) -> &Self::Target { + self.group() + } +} + + + + /// A group is a way of setting permissions for a whole set of users. /// /// Users have groups, not the other way around. @@ -51,21 +147,6 @@ pub struct Group inherits: Option>, } -impl Group -{ - /* -//TODO: Create bespoke iterator type for this, it's not possible here. - pub fn inherits<'b, 'a>(&'b self, space: &'a Userspace) -> impl Iterator +'a - where 'b: 'a - { - match &self.inherits { - Some(inherits) => inherits.iter() - .filter_map(|group| group.find_in_space(space).map(|parent| parent.inherits(space))).flatten(), - None => todo!() - } - }*/ -} - pub trait AsEntityId { fn entity_id(&self) -> Cow<'_, EntityID>; @@ -290,4 +371,24 @@ impl Userspace { ent.entity_id().find_in_space(self).is_some() } + + /// Get a user reference from their ID + pub fn user_ref(&self, id: UserID) -> Option> + { + if self.users.contains_key(&id) { + Some(UserRef(id, &self)) + } else { + None + } + } + + /// Get a group reference from their ID + pub fn group_ref(&self, id: GroupID) -> Option> + { + if self.groups.contains_key(&id) { + Some(GroupRef(id, &self)) + } else { + None + } + } }