shared_singleton

Crates.ioshared_singleton
lib.rsshared_singleton
version0.2.1
sourcesrc
created_at2020-10-09 18:16:35.799404
updated_at2024-03-03 08:43:57.073951
descriptionThe shared_singleton trait provides singleton pattern state management with shared container.
homepagehttps://github.com/kan1-u/shared_singleton
repository
max_upload_size
id297777
size14,287
Kanichi Uegaki (kan1-u)

documentation

https://docs.rs/shared_singleton

README

Shared Singleton

The shared_singleton trait provides singleton pattern state management with shared container.

Implement the singleton pattern with very short code are available.
You can choose the better shared container from Rc<T>, Rc<Cell<T>>, Rc<RefCell<T>>, Arc<T>, Arc<Mutex<T>> and Arc<RwLock<T>>.

Examples

  • Rc<T>
use shared_singleton::*;

struct Foo(usize);
impl_singleton_rc!(Foo, Foo(1));

let x1 = Foo::singleton();
let x2 = Foo::singleton();

assert_eq!(1, Foo::singleton().0);

assert!(std::rc::Rc::ptr_eq(&x1, &x2));
  • Rc<Cell<T>>
use shared_singleton::*;

#[derive(Clone, Copy)]
struct Foo(usize);
impl_singleton_rc_cell!(Foo, Foo(1));

let x1 = Foo::singleton();
let x2 = Foo::singleton();

assert_eq!(1, x1.get().0);
x2.set(Foo(2));
assert_eq!(2, x1.get().0);

assert!(std::rc::Rc::ptr_eq(&x1, &x2));
  • Rc<RefCell<T>>
use shared_singleton::*;

struct Foo(usize);
impl_singleton_rc_refcell!(Foo, Foo(1));

let x1 = Foo::singleton();
let x2 = Foo::singleton();

assert_eq!(1, x1.borrow().0);
x2.borrow_mut().0 = 2;
assert_eq!(2, x1.borrow().0);

assert!(std::rc::Rc::ptr_eq(&x1, &x2));
  • Arc<T>
use shared_singleton::*;

struct Foo(usize);
impl_singleton_arc!(Foo, Foo(1));

let x1 = Foo::singleton();
let x2 = Foo::singleton();

assert_eq!(1, x1.0);

assert!(std::sync::Arc::ptr_eq(&x1, &x2));
  • Arc<Mutex<T>>
use shared_singleton::*;

struct Foo(usize);
impl_singleton_arc_mutex!(Foo, Foo(1));

let x1 = Foo::singleton();
let x2 = Foo::singleton();

assert!(std::sync::Arc::ptr_eq(&x1, &x2));

let t1 = std::thread::spawn(move || {
    x1.lock().unwrap().0 = 2;
    println!("{}", x1.lock().unwrap().0);
});

let t2 = std::thread::spawn(move || {
    x2.lock().unwrap().0 = 3;
    println!("{}", x2.lock().unwrap().0);
});

t1.join().unwrap();
t2.join().unwrap();
  • Arc<RwLock<T>>
use shared_singleton::*;

struct Foo(usize);
impl_singleton_arc_rwlock!(Foo, Foo(1));

let x1 = Foo::singleton();
let x2 = Foo::singleton();

assert!(std::sync::Arc::ptr_eq(&x1, &x2));

let t1 = std::thread::spawn(move || {
    x1.write().unwrap().0 = 2;
    println!("{}", x1.read().unwrap().0);
});

let t2 = std::thread::spawn(move || {
    x2.write().unwrap().0 = 3;
    println!("{}", x2.read().unwrap().0);
});

t1.join().unwrap();
t2.join().unwrap();

Optional Features

tokio

tokio::sync::Mutex and tokio::sync::RwLock are available.

  • tokio::sync::Mutex
use shared_singleton::*;

struct Foo(usize);
impl_singleton_arc_mutex_tokio!(Foo, Foo(1));

#[tokio::main]
async fn main() {
    let x1 = Foo::singleton();
    let x2 = Foo::singleton();

    assert!(std::sync::Arc::ptr_eq(&x1, &x2));

    let t1 = tokio::spawn(async move {
        x1.lock().await.0 = 2;
        println!("{}", x1.lock().await.0);
    });

    let t2 = tokio::spawn(async move {
        x2.lock().await.0 = 3;
        println!("{}", x2.lock().await.0);
    });

    t1.await.unwrap();
    t2.await.unwrap();
}
  • tokio::sync::RwLock
use shared_singleton::*;

struct Foo(usize);
impl_singleton_arc_rwlock_tokio!(Foo, Foo(1));

#[tokio::main]
async fn main() {
    let x1 = Foo::singleton();
    let x2 = Foo::singleton();

    assert!(std::sync::Arc::ptr_eq(&x1, &x2));

    let t1 = tokio::spawn(async move {
        x1.write().await.0 = 2;
        println!("{}", x1.read().await.0);
    });

    let t2 = tokio::spawn(async move {
        x2.write().await.0 = 3;
        println!("{}", x2.read().await.0);
    });

    t1.await.unwrap();
    t2.await.unwrap();
}
Commit count: 0

cargo fmt