1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
use std::time::{SystemTime, UNIX_EPOCH};
use crate::{const_panic_new, INSTANCE_MAX};
/// A builder for a snowflake Generator. This builder can be used for both [`Generator`] and
/// [`sync::Generator`].
///
/// [`Generator`]: crate::Generator
/// [`sync::Generator`]: crate::sync::Generator
#[derive(Copy, Clone, Debug)]
pub struct Builder {
pub(crate) instance: u16,
pub(crate) epoch: SystemTime,
}
impl Builder {
/// Creates a new `Builder` with the instance set to `0` and epoch set to [`UNIX_EPOCH`].
///
/// # Examples
///
/// ```
/// # use std::time::UNIX_EPOCH;
/// # use snowflaked::{Builder, Generator};
/// #
/// let generator: Generator = Builder::new().build();
///
/// assert_eq!(generator.instance(), 0);
/// assert_eq!(generator.epoch(), UNIX_EPOCH);
/// ```
#[inline]
pub const fn new() -> Self {
Self {
instance: 0,
epoch: UNIX_EPOCH,
}
}
/// Sets the `instance` value of the `Builder`.
///
/// # Panics
///
/// Panics if the provided `instance` exceeds the maximum value (2^10 -1).
///
/// # Examples
///
/// ```
/// # use snowflaked::{Builder, Generator};
/// #
/// let generator: Generator = Builder::new().instance(400).build();
///
/// assert_eq!(generator.instance(), 400);
/// ```
///
/// Providing an invalid `instance` panics:
///
/// ```should_panic
/// # use snowflaked::{Builder, Generator};
/// #
/// let generator: Generator = Builder::new().instance(5000).build();
/// ```
#[inline]
pub const fn instance(self, instance: u16) -> Self {
match self.instance_checked(instance) {
Some(this) => this,
None => const_panic_new(),
}
}
/// Sets the `instance` value of the `Builder`. Returns `None` if the provided `instance`
/// exceeds the maximum value (2^10 -1).
///
/// # Examples
///
/// ```
/// # use snowflaked::{Builder, Generator};
/// #
/// let builder = Builder::new().instance_checked(400);
/// assert!(builder.is_some());
/// ```
///
/// Providing an invalid `instance` returns `None`:
///
/// ```
/// # use snowflaked::{Builder, Generator};
/// #
/// let builder = Builder::new().instance_checked(5000);
/// assert!(builder.is_none());
/// ```
#[inline]
pub const fn instance_checked(mut self, instance: u16) -> Option<Self> {
if instance > INSTANCE_MAX {
None
} else {
self.instance = instance;
Some(self)
}
}
/// Sets the `instance` value of the `Builder` without validating whether `instance` exceeds
/// the maximum value (2^10 - 1).
///
/// # Examples
///
/// ```
/// # use snowflaked::{Builder, Generator};
/// #
/// let generator: Generator = Builder::new().instance_unchecked(400).build();
///
/// assert_eq!(generator.instance(), 400);
/// ```
#[inline]
pub const fn instance_unchecked(mut self, instance: u16) -> Self {
self.instance = instance;
self
}
#[inline]
pub const fn epoch(mut self, epoch: SystemTime) -> Self {
self.epoch = epoch;
self
}
/// Consumes this `Builder`, returning the constructed generator. This function works with both
/// [`Generator`] and [`sync::Generator`].
///
/// # Examples
///
/// ```
/// use snowflaked::{Builder, Generator};
///
/// let mut generator = Builder::new().build::<Generator>();
///
/// let id: u64 = generator.generate();
/// ```
///
/// A [`sync::Generator`] can be constructed in the same way:
///
/// ```
/// use snowflaked::Builder;
/// use snowflaked::sync::Generator;
///
/// let generator = Builder::new().build::<Generator>();
///
/// let id: u64 = generator.generate();
/// ```
///
/// [`Generator`]: crate::Generator
/// [`sync::Generator`]: crate::sync::Generator
#[inline]
pub fn build<T>(self) -> T
where
T: From<Self>,
{
T::from(self)
}
}