#![forbid(unsafe_code)]
#![warn(missing_docs)]
use std::fmt::Display;
use std::sync::atomic::{AtomicU32, Ordering};
use serde::{Deserialize, Serialize};
#[allow(missing_docs, non_snake_case)]
#[allow(clippy::derive_partial_eq_without_eq)]
pub mod proto {
tonic::include_proto!("sshx");
pub const FILE_DESCRIPTOR_SET: &[u8] = tonic::include_file_descriptor_set!("sshx");
}
pub fn rand_alphanumeric(len: usize) -> String {
use rand::{distributions::Alphanumeric, thread_rng, Rng};
thread_rng()
.sample_iter(Alphanumeric)
.take(len)
.map(char::from)
.collect()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Sid(pub u32);
impl Display for Sid {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Uid(pub u32);
impl Display for Uid {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug)]
pub struct IdCounter {
next_sid: AtomicU32,
next_uid: AtomicU32,
}
impl Default for IdCounter {
fn default() -> Self {
Self {
next_sid: AtomicU32::new(1),
next_uid: AtomicU32::new(1),
}
}
}
impl IdCounter {
pub fn next_sid(&self) -> Sid {
Sid(self.next_sid.fetch_add(1, Ordering::Relaxed))
}
pub fn next_uid(&self) -> Uid {
Uid(self.next_uid.fetch_add(1, Ordering::Relaxed))
}
pub fn get_current_values(&self) -> (Sid, Uid) {
(
Sid(self.next_sid.load(Ordering::Relaxed)),
Uid(self.next_uid.load(Ordering::Relaxed)),
)
}
pub fn set_current_values(&self, sid: Sid, uid: Uid) {
self.next_sid.store(sid.0, Ordering::Relaxed);
self.next_uid.store(uid.0, Ordering::Relaxed);
}
}