#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct SemaphoreConfig {
pub max_count: usize,
}
#[derive(Debug, Clone)]
pub struct SemaphoreCounter {
config: SemaphoreConfig,
current: usize,
}
#[allow(dead_code)]
pub fn default_semaphore_config() -> SemaphoreConfig {
SemaphoreConfig { max_count: 1 }
}
#[allow(dead_code)]
pub fn new_semaphore_counter(config: SemaphoreConfig) -> SemaphoreCounter {
SemaphoreCounter { config, current: 0 }
}
#[allow(dead_code)]
pub fn sem_acquire(sem: &mut SemaphoreCounter) -> bool {
if sem.current < sem.config.max_count {
sem.current += 1;
true
} else {
false
}
}
#[allow(dead_code)]
pub fn sem_release(sem: &mut SemaphoreCounter) -> bool {
if sem.current > 0 {
sem.current -= 1;
true
} else {
false
}
}
#[allow(dead_code)]
pub fn sem_try_acquire(sem: &mut SemaphoreCounter) -> bool {
sem_acquire(sem)
}
#[allow(dead_code)]
pub fn sem_available(sem: &SemaphoreCounter) -> usize {
sem.config.max_count.saturating_sub(sem.current)
}
#[allow(dead_code)]
pub fn sem_max_count(sem: &SemaphoreCounter) -> usize {
sem.config.max_count
}
#[allow(dead_code)]
pub fn sem_is_full(sem: &SemaphoreCounter) -> bool {
sem.current >= sem.config.max_count
}
#[allow(dead_code)]
pub fn sem_to_json(sem: &SemaphoreCounter) -> String {
format!(
"{{\"max_count\":{},\"current\":{},\"available\":{}}}",
sem.config.max_count,
sem.current,
sem_available(sem)
)
}
#[allow(dead_code)]
pub fn sem_reset(sem: &mut SemaphoreCounter) {
sem.current = 0;
}
#[cfg(test)]
mod tests {
use super::*;
fn make_sem(max: usize) -> SemaphoreCounter {
new_semaphore_counter(SemaphoreConfig { max_count: max })
}
#[test]
fn test_initial_available() {
let sem = make_sem(3);
assert_eq!(sem_available(&sem), 3);
}
#[test]
fn test_acquire_reduces_available() {
let mut sem = make_sem(3);
assert!(sem_acquire(&mut sem));
assert_eq!(sem_available(&sem), 2);
}
#[test]
fn test_acquire_fails_when_full() {
let mut sem = make_sem(1);
assert!(sem_acquire(&mut sem));
assert!(!sem_acquire(&mut sem));
}
#[test]
fn test_release_increases_available() {
let mut sem = make_sem(2);
sem_acquire(&mut sem);
sem_release(&mut sem);
assert_eq!(sem_available(&sem), 2);
}
#[test]
fn test_release_below_zero_fails() {
let mut sem = make_sem(1);
assert!(!sem_release(&mut sem));
}
#[test]
fn test_is_full() {
let mut sem = make_sem(1);
assert!(!sem_is_full(&sem));
sem_acquire(&mut sem);
assert!(sem_is_full(&sem));
}
#[test]
fn test_reset() {
let mut sem = make_sem(2);
sem_acquire(&mut sem);
sem_acquire(&mut sem);
sem_reset(&mut sem);
assert_eq!(sem_available(&sem), 2);
}
#[test]
fn test_max_count() {
let sem = make_sem(5);
assert_eq!(sem_max_count(&sem), 5);
}
#[test]
fn test_to_json_contains_max_count() {
let sem = make_sem(4);
let json = sem_to_json(&sem);
assert!(json.contains("\"max_count\":4"));
}
#[test]
fn test_try_acquire_same_as_acquire() {
let mut sem = make_sem(1);
assert!(sem_try_acquire(&mut sem));
assert!(!sem_try_acquire(&mut sem));
}
}