change mb64 a little

master
Avril 4 years ago
parent 370276fb56
commit 070c180303
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -11,13 +11,16 @@ use regex::{
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 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!{ lazy_static!{
static ref BASE64_CONV_TABLE: smallmap::Map<char, char> = smallmap![ static ref BASE64_CONV_TABLE: smallmap::Map<char, char> = smallmap![
{'/' => '_'}, {'/' => '_'},
{'+' => '-'}, {'+' => '-'},
{'=' => '~'},
]; ];
static ref BASE64_CONV_TABLE_REV: smallmap::Map<char, char> = BASE64_CONV_TABLE.clone().reverse(); static ref BASE64_CONV_TABLE_REV: smallmap::Map<char, char> = 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"); 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)] #[derive(Debug)]
pub struct Base64Error<T>(T); pub struct Base64Error<T>(T);

@ -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!()
}

@ -2,6 +2,7 @@
use super::*; use super::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::borrow::Cow; use std::borrow::Cow;
use std::ops::Deref;
use bitflags::bitflags; use bitflags::bitflags;
@ -28,6 +29,101 @@ pub struct User
groups: Vec<GroupID>, groups: Vec<GroupID>,
} }
/// 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. /// A group is a way of setting permissions for a whole set of users.
/// ///
/// Users have groups, not the other way around. /// Users have groups, not the other way around.
@ -51,21 +147,6 @@ pub struct Group
inherits: Option<Vec<GroupID>>, inherits: Option<Vec<GroupID>>,
} }
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<Item = GroupID> +'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 pub trait AsEntityId
{ {
fn entity_id(&self) -> Cow<'_, EntityID>; fn entity_id(&self) -> Cow<'_, EntityID>;
@ -290,4 +371,24 @@ impl Userspace
{ {
ent.entity_id().find_in_space(self).is_some() ent.entity_id().find_in_space(self).is_some()
} }
/// Get a user reference from their ID
pub fn user_ref(&self, id: UserID) -> Option<UserRef<'_>>
{
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<GroupRef<'_>>
{
if self.groups.contains_key(&id) {
Some(GroupRef(id, &self))
} else {
None
}
}
} }

Loading…
Cancel
Save