idgenerator/
instance.rs

1//! # Instance
2//!
3//! Provide two out-of-the-box implementations of id generators:
4//!
5//! - `IdInstance`: a instance with only one generator. See [examples/single.rs](https://github.com/BobAnkh/idgenerator/blob/main/examples/single.rs) for usage example.
6//! - `IdVecInstance`: a instance with multiple generators. See [examples/multiple.rs](https://github.com/BobAnkh/idgenerator/blob/main/examples/multiple.rs) for usage example.
7
8use once_cell::sync::OnceCell;
9use parking_lot::{Mutex, RwLock};
10use std::sync::Arc;
11
12use crate::CoreIdGenerator;
13use crate::IdGeneratorOptions;
14use crate::OptionError;
15
16/// Instance of only one generator
17pub struct IdInstance;
18
19impl IdInstance {
20    /// Initialize the instance
21    pub fn init(options: IdGeneratorOptions) -> Result<(), OptionError> {
22        IdInstance::get_instance().lock().init(options)
23    }
24
25    /// Set instance options
26    pub fn set_options(options: IdGeneratorOptions) -> Result<(), OptionError> {
27        IdInstance::get_instance().lock().set_options(options)
28    }
29
30    /// Get instance options
31    pub fn get_options() -> IdGeneratorOptions {
32        IdInstance::get_instance().lock().get_options()
33    }
34
35    /// Get a unique id
36    pub fn next_id() -> i64 {
37        IdInstance::get_instance().lock().next_id()
38    }
39
40    fn get_instance() -> &'static Mutex<CoreIdGenerator> {
41        static INSTANCE: OnceCell<Mutex<CoreIdGenerator>> = OnceCell::new();
42        INSTANCE.get_or_init(|| Mutex::new(CoreIdGenerator::default()))
43    }
44}
45
46/// Instance of multiple generators contained in a vector
47pub struct IdVecInstance;
48
49impl IdVecInstance {
50    /// Initialize the instance
51    ///
52    /// Every time you call this function will drop all the previous generators in the instance.
53    pub fn init(mut options: Vec<IdGeneratorOptions>) -> Result<(), OptionError> {
54        if options.is_empty() {
55            return Err(OptionError::InvalidVecLen(0));
56        }
57        let mut instances = IdVecInstance::get_instance().write();
58        instances.clear();
59        for option in options.drain(..) {
60            let mut instance = CoreIdGenerator::default();
61            instance.init(option)?;
62            instances.push(Arc::new(Mutex::new(instance)));
63        }
64        Ok(())
65    }
66
67    /// Set instance options of the given index
68    pub fn set_options(index: usize, options: IdGeneratorOptions) -> Result<(), OptionError> {
69        let reader = {
70            let r = IdVecInstance::get_instance().read();
71            if index >= r.len() {
72                return Err(OptionError::IndexOutOfRange(index));
73            }
74            Arc::clone(&r[index])
75        };
76        reader.lock().set_options(options)?;
77        Ok(())
78    }
79
80    /// Get instance options of the given index
81    pub fn get_options(index: usize) -> Result<IdGeneratorOptions, OptionError> {
82        let reader = {
83            let r = IdVecInstance::get_instance().read();
84            if index >= r.len() {
85                return Err(OptionError::IndexOutOfRange(index));
86            }
87            Arc::clone(&r[index])
88        };
89        let options = reader.lock().get_options();
90        Ok(options)
91    }
92
93    /// Get a unique id
94    pub fn next_id(index: usize) -> i64 {
95        // Because this step matters the speed a lot,
96        // so we won't check the index and let it panic
97        let reader = {
98            let r = IdVecInstance::get_instance().read();
99            Arc::clone(&r[index])
100        };
101        let id = reader.lock().next_id();
102        id
103    }
104
105    fn get_instance() -> &'static RwLock<Vec<Arc<Mutex<CoreIdGenerator>>>> {
106        static INSTANCE: OnceCell<RwLock<Vec<Arc<Mutex<CoreIdGenerator>>>>> = OnceCell::new();
107        INSTANCE.get_or_init(|| RwLock::new(Vec::new()))
108    }
109}