direct_http 0.5.5

An simple and low-level rust REST API library.
Documentation
use std::collections::HashMap;
use std::sync::{ Mutex, Arc };

pub struct MutexLimiter(Arc<Mutex<Limiter>>);

impl MutexLimiter {
	pub fn new(limit_per_client: i32, limit_per_server: i32) -> Self {
		MutexLimiter(Arc::new(Mutex::new(Limiter::new(limit_per_client, limit_per_server))))
	}

	pub fn start(&self) {
		let clone = self.clone();
		std::thread::spawn(move || {
			loop {
				clone.decrease_all();
				std::thread::sleep(std::time::Duration::from_millis(100));
			}
		});

		let clone = self.clone();
		std::thread::spawn(move || {
			loop {
				clone.remove_empty_clients();
				std::thread::sleep(std::time::Duration::from_millis(120000));
			}
		});
	}

	fn decrease_all(&self) {
		let mut limiter = self.0.lock().unwrap();
		limiter.decrease_all();
	}

	fn remove_empty_clients(&self) {
		let mut limiter = self.0.lock().unwrap();
		limiter.remove_empty_clients();
	}

	pub fn clone(&self) -> Self {
		MutexLimiter(Arc::clone(&self.0))
	}

	pub fn server_allow(&self) -> bool {
		let mut limiter = self.0.lock().unwrap();
		limiter.server_allow()
	}

	pub fn client_allow(&self, ip: String) -> bool {
		let mut limiter = self.0.lock().unwrap();
		limiter.client_allow(ip)
	}
}

pub struct Limiter {
	pub limit_per_client: i32,
	pub limit_per_server: i32,

	client_decreaser: i32,
	server_decreaser: i32,

	server: i32,

	clients: HashMap<String, i32>,
}

impl Limiter {
	pub fn new(mut limit_per_client: i32, mut limit_per_server: i32) -> Self {
		if limit_per_client < 10 {
			limit_per_client = 10;
		}

		if limit_per_server < 10 {
			limit_per_server = 10;
		}

		Limiter {
			limit_per_client,
			limit_per_server,

			client_decreaser: limit_per_client / 10,
			server_decreaser: limit_per_server / 10,

			server: 0,
			clients: HashMap::new(),
		}
	}

	fn remove_empty_clients(&mut self) {
		self.clients.retain(|_, v| *v > 0);
	}

	fn decrease_all(&mut self) {
		if self.server > 0 {
			self.server -= self.server_decreaser;
		}

		for client in self.clients.values_mut() {
			if *client > 0 {
				*client -= self.client_decreaser;
			}
		}
	}

	fn server_allow(&mut self) -> bool {
		self.server += 1;

		if self.server > self.limit_per_server {
			self.server -= 1;
			false
		} else {
			true
		}
	}

	fn client_allow(&mut self, ip: String) -> bool {
		let client = self.clients.entry(ip).or_insert(0);

		*client += 1;

		if *client > self.limit_per_client {
			*client -= 1;
			false
		} else {
			true
		}
	}
}