148 lines
3.2 KiB
Rust
148 lines
3.2 KiB
Rust
|
|
use std::collections::{HashMap, HashSet, BTreeMap};
|
||
|
|
use std::rc::Rc;
|
||
|
|
use std::cell::RefCell;
|
||
|
|
use std::sync::{Arc, Mutex};
|
||
|
|
use std::marker::PhantomData;
|
||
|
|
|
||
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||
|
|
pub enum Status {
|
||
|
|
Active,
|
||
|
|
Inactive,
|
||
|
|
Pending,
|
||
|
|
Banned,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug)]
|
||
|
|
pub struct TreeNode<T> {
|
||
|
|
pub value: T,
|
||
|
|
pub left: Option<Box<TreeNode<T>>>,
|
||
|
|
pub right: Option<Box<TreeNode<T>>>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl<T: Ord> TreeNode<T> {
|
||
|
|
pub fn insert(&mut self, value: T) {
|
||
|
|
let target = if value <= self.value {
|
||
|
|
&mut self.left
|
||
|
|
} else {
|
||
|
|
&mut self.right
|
||
|
|
};
|
||
|
|
match target {
|
||
|
|
Some(node) => node.insert(value),
|
||
|
|
None => *target = Some(Box::new(TreeNode {
|
||
|
|
value,
|
||
|
|
left: None,
|
||
|
|
right: None,
|
||
|
|
})),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn contains(&self, value: &T) -> bool {
|
||
|
|
&self.value == value
|
||
|
|
|| self.left.as_ref().map_or(false, |n| n.contains(value))
|
||
|
|
|| self.right.as_ref().map_or(false, |n| n.contains(value))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub trait Monoid {
|
||
|
|
fn empty() -> Self;
|
||
|
|
fn combine(&self, other: &Self) -> Self;
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Monoid for i32 {
|
||
|
|
fn empty() -> Self { 0 }
|
||
|
|
fn combine(&self, other: &Self) -> Self { self + other }
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Monoid for String {
|
||
|
|
fn empty() -> Self { String::new() }
|
||
|
|
fn combine(&self, other: &Self) -> Self { format!("{}{}", self, other) }
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn reduce<T: Monoid>(items: &[T]) -> T {
|
||
|
|
items.iter().fold(T::empty(), |acc, x| acc.combine(x))
|
||
|
|
}
|
||
|
|
|
||
|
|
macro_rules! vec_of_strings {
|
||
|
|
($($x:expr),*) => (vec![$($x.to_string()),*]);
|
||
|
|
}
|
||
|
|
|
||
|
|
pub struct Lazy<T, F = fn() -> T>
|
||
|
|
where
|
||
|
|
F: Fn() -> T,
|
||
|
|
{
|
||
|
|
value: Option<T>,
|
||
|
|
factory: F,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl<T, F: Fn() -> T> Lazy<T, F> {
|
||
|
|
pub fn new(factory: F) -> Self {
|
||
|
|
Self {
|
||
|
|
value: None,
|
||
|
|
factory,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn get(&mut self) -> &T {
|
||
|
|
self.value.get_or_insert_with(&self.factory)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub async fn parallel_map<T, U, F>(items: Vec<T>, f: F) -> Vec<U>
|
||
|
|
where
|
||
|
|
T: Send + 'static,
|
||
|
|
U: Send + 'static,
|
||
|
|
F: Fn(T) -> U + Send + Sync + 'static,
|
||
|
|
{
|
||
|
|
use tokio::task;
|
||
|
|
let mut handles = Vec::new();
|
||
|
|
for item in items {
|
||
|
|
handles.push(task::spawn(async move { f(item) }));
|
||
|
|
}
|
||
|
|
let mut results = Vec::new();
|
||
|
|
for handle in handles {
|
||
|
|
results.push(handle.await.unwrap());
|
||
|
|
}
|
||
|
|
results
|
||
|
|
}
|
||
|
|
|
||
|
|
pub struct CustomIterator<T> {
|
||
|
|
items: Vec<T>,
|
||
|
|
index: usize,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl<T: Clone> Iterator for CustomIterator<T> {
|
||
|
|
type Item = T;
|
||
|
|
fn next(&mut self) -> Option<Self::Item> {
|
||
|
|
if self.index < self.items.len() {
|
||
|
|
let item = self.items[self.index].clone();
|
||
|
|
self.index += 1;
|
||
|
|
Some(item)
|
||
|
|
} else {
|
||
|
|
None
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const DEFAULT_PORT: u16 = 8080;
|
||
|
|
static APP_NAME: &str = "nimcheck-rs";
|
||
|
|
thread_local! {
|
||
|
|
static CACHE: RefCell<HashMap<String, String>> = RefCell::new(HashMap::new());
|
||
|
|
}
|
||
|
|
|
||
|
|
unsafe impl Send for User {}
|
||
|
|
unsafe impl Sync for User {}
|
||
|
|
|
||
|
|
#[cfg(test)]
|
||
|
|
mod tests {
|
||
|
|
use super::*;
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_insert() {
|
||
|
|
let mut root = TreeNode { value: 5, left: None, right: None };
|
||
|
|
root.insert(3);
|
||
|
|
root.insert(7);
|
||
|
|
assert!(root.contains(&3));
|
||
|
|
assert!(root.contains(&7));
|
||
|
|
}
|
||
|
|
}
|