parent
eeea6a13b1
commit
1212bfdb12
@ -0,0 +1,65 @@
|
|||||||
|
use super::*;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use tokio::time::{
|
||||||
|
DelayQueue,
|
||||||
|
delay_queue,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Cache
|
||||||
|
{
|
||||||
|
//TODO: HashMap and DelayQueue of mapping public keys to user IDs, etc.
|
||||||
|
pkey_maps: HashMap<String, (UserID, delay_queue::Key)>,
|
||||||
|
pkey_rems: DelayQueue<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cache
|
||||||
|
{
|
||||||
|
/// Create a new empty cache
|
||||||
|
pub fn new() -> Self
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
pkey_maps: HashMap::new(),
|
||||||
|
pkey_rems: DelayQueue::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//how tf do we get this to run concurrently with insertions??? it holds `&mut self` forever!
|
||||||
|
//redesign required. maybe using Arc and RwLock or Mutex and interrupting the purge task when something needs to be inserted. i.e: give this task a stream that it can `select!` along with calling `next()`, if the other future completes first, we return? but wouldn't that lose us an item in `next()`? is there a `select with priority` in `futures`? i think there is. eh...
|
||||||
|
/// Run a purge on this cache.
|
||||||
|
pub async fn purge(&mut self) -> eyre::Result<()>
|
||||||
|
{
|
||||||
|
let mut errors = Vec::default();
|
||||||
|
while let Some(entry) = self.pkey_rems.next().await
|
||||||
|
{
|
||||||
|
match entry {
|
||||||
|
Ok(entry) => {
|
||||||
|
self.pkey_maps.remove(entry.get_ref());
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
errors.push(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errors.len() > 0 {
|
||||||
|
let mut err = Err(eyre!("One or more removals failed"))
|
||||||
|
.with_note(|| errors.len().to_string().header("Number of failed removals"));
|
||||||
|
for e in errors.into_iter()
|
||||||
|
{
|
||||||
|
err = err.with_error(move || e);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Purge all values available to be purged now.
|
||||||
|
pub fn purge_now(&mut self) -> eyre::Result<()>
|
||||||
|
{
|
||||||
|
match self.purge().now_or_never() {
|
||||||
|
Some(x) => x,
|
||||||
|
None => Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,207 @@
|
|||||||
|
use std::fmt;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
/// Represents a semver version number of the order `major.minor.bugfix`.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] //TODO: Make these impls instead of derives, because safe packed borrows.
|
||||||
|
#[repr(C, packed)]
|
||||||
|
pub struct Version(u8,u8,u16);
|
||||||
|
|
||||||
|
impl fmt::Display for Version
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||||
|
{
|
||||||
|
write!(f, "{}.{}.{}", self.major(), self.minor(), self.bugfix())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u32> for Version
|
||||||
|
{
|
||||||
|
#[inline] fn from(from: u32) -> Self
|
||||||
|
{
|
||||||
|
Self::from_u32(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Version> for u32
|
||||||
|
{
|
||||||
|
fn from(from: Version) -> Self
|
||||||
|
{
|
||||||
|
from.to_u32()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<Version> for u32
|
||||||
|
{
|
||||||
|
#[inline] fn eq(&self, other: &Version) -> bool
|
||||||
|
{
|
||||||
|
*self == other.to_u32()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PartialEq<u32> for Version
|
||||||
|
{
|
||||||
|
#[inline] fn eq(&self, other: &u32) -> bool
|
||||||
|
{
|
||||||
|
self.to_u32() == *other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PartialOrd<u32> for Version
|
||||||
|
{
|
||||||
|
#[inline] fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
|
||||||
|
self.to_u32().partial_cmp(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PartialOrd<Version> for u32
|
||||||
|
{
|
||||||
|
#[inline] fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
|
||||||
|
self.partial_cmp(&other.to_u32())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<()> for Version
|
||||||
|
{
|
||||||
|
#[inline] fn from(from: ()) -> Self
|
||||||
|
{
|
||||||
|
Self(0,0,0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl From<(usize,)> for Version
|
||||||
|
{
|
||||||
|
#[inline] fn from(from: (usize,)) -> Self
|
||||||
|
{
|
||||||
|
Self::new(from.0,0,0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl From<(usize, usize)> for Version
|
||||||
|
{
|
||||||
|
#[inline] fn from((ma, mi): (usize, usize)) -> Self
|
||||||
|
{
|
||||||
|
Self::new(ma, mi, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl From<(usize, usize, usize)> for Version
|
||||||
|
{
|
||||||
|
#[inline] fn from((ma,mi,bu): (usize, usize, usize)) -> Self
|
||||||
|
{
|
||||||
|
Self::new(ma,mi,bu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(u8, u8, u16)> for Version
|
||||||
|
{
|
||||||
|
#[inline] fn from((ma, mi, bu): (u8, u8, u16)) -> Self
|
||||||
|
{
|
||||||
|
Self(ma,mi,bu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Version> for (u8, u8, u16)
|
||||||
|
{
|
||||||
|
#[inline] fn from(from: Version) -> Self
|
||||||
|
{
|
||||||
|
(from.0, from.1, from.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Version> for (usize, usize, usize)
|
||||||
|
{
|
||||||
|
#[inline] fn from(from: Version) -> Self
|
||||||
|
{
|
||||||
|
(from.major(), from.minor(), from.bugfix())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Version
|
||||||
|
{
|
||||||
|
/// The major component of this `Version`.
|
||||||
|
#[inline] pub const fn major(self) -> usize
|
||||||
|
{
|
||||||
|
self.0 as usize
|
||||||
|
}
|
||||||
|
/// The minor component of this `Version`.
|
||||||
|
#[inline] pub const fn minor(self) -> usize
|
||||||
|
{
|
||||||
|
self.1 as usize
|
||||||
|
}
|
||||||
|
/// The bugfix component of this `Version`.
|
||||||
|
#[inline] pub const fn bugfix(self) -> usize
|
||||||
|
{
|
||||||
|
self.2 as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert to a 32 bit integer representation
|
||||||
|
#[inline] pub const fn to_u32(self) -> u32
|
||||||
|
{
|
||||||
|
let mb = self.2.to_be_bytes();
|
||||||
|
u32::from_be_bytes([
|
||||||
|
self.0,
|
||||||
|
self.1,
|
||||||
|
mb[0],
|
||||||
|
mb[1],
|
||||||
|
])
|
||||||
|
}
|
||||||
|
/// Convert to a 32 bit integer representation
|
||||||
|
#[inline] pub const fn from_u32(from: u32) -> Self
|
||||||
|
{
|
||||||
|
let bytes = from.to_be_bytes();
|
||||||
|
Self(
|
||||||
|
bytes[0],
|
||||||
|
bytes[1],
|
||||||
|
u16::from_be_bytes([bytes[2], bytes[3]]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new version object
|
||||||
|
#[inline] pub const fn new_exact(major: u8, minor: u8, bugfix: u16) -> Self
|
||||||
|
{
|
||||||
|
Self(major,minor,bugfix)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new version object
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// If any of the components do not fit within their bounds.
|
||||||
|
#[inline] pub fn new(major: usize, minor: usize, bugfix: usize) -> Self
|
||||||
|
{
|
||||||
|
use std::convert::TryInto;
|
||||||
|
Self::new_exact(major.try_into().expect("Major exceeded limit of u8"),
|
||||||
|
minor.try_into().expect("Minor exceeded limit of u8"),
|
||||||
|
bugfix.try_into().expect("Bugfix exceeded limit of u16"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export] macro_rules! version {
|
||||||
|
($maj:expr, $min:expr, $bfx:expr) => ($crate::version::Version::new_exact($maj as u8, $min as u8, $bfx as u16));
|
||||||
|
($maj:expr, $min:expr) => ($crate::version::Version::new_exact($maj as u8, $min as u8, 0));
|
||||||
|
($maj:expr) => ($crate::version::Version::new_exact($maj as u8, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests
|
||||||
|
{
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn ordinal()
|
||||||
|
{
|
||||||
|
assert!( version!(1) > version!(0, 9, 1));
|
||||||
|
assert!( version!(2) > version!(1, 9, 300));
|
||||||
|
assert!( (version!(1)..version!(1, 9)).contains(&version!(1, 8)));
|
||||||
|
assert!( !(version!(1)..version!(2)).contains(&version!(2, 10, 432)));
|
||||||
|
|
||||||
|
println!("{}: {}", version!(1), version!(1).to_u32());
|
||||||
|
println!("{}: {}", version!(0,9,1), version!(0,9,1).to_u32());
|
||||||
|
|
||||||
|
assert!( version!(1).to_u32() > version!(0, 9, 1).to_u32());
|
||||||
|
assert!( version!(2).to_u32() > version!(1, 9, 300).to_u32());
|
||||||
|
assert!( (version!(1).to_u32()..version!(1, 9).to_u32()).contains(&version!(1, 8).to_u32()));
|
||||||
|
assert!( !(version!(1).to_u32()..version!(2).to_u32()).contains(&version!(2, 10, 432).to_u32()));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue