snowid 3.0.0

A Rust library for generating SnowID - a Snowflake-like timestamp-based distributed unique identifier
Documentation
#[cfg(test)]
mod tests {
    use crate::tests::test_utils::{assert_ids_monotonic, assert_unique_ids, wall_clock_ms};
    use crate::*;
    use proptest::prelude::*;

    proptest! {
        #[test]
        fn generate_batch_preserves_uniqueness_and_layout(node_bits in 6u8..=16, batch_len in 1usize..=8192) {
            let config = SnowIDConfig::builder().node_bits(node_bits).unwrap().build();
            let generator = SnowID::with_config(1, config).unwrap();
            let mut ids = vec![0u64; batch_len];

            generator.generate_batch(&mut ids);

            assert_unique_ids(&ids, ids.len());
            assert_ids_monotonic(&ids);
            for id in ids {
                let (timestamp, node, sequence) = generator.extract.decompose(id);
                prop_assert!(timestamp <= SnowID::MAX_TIMESTAMP);
                prop_assert_eq!(node, 1);
                prop_assert!(sequence <= generator.config.max_sequence_id());
            }
        }

        #[test]
        fn generate_is_monotonic_under_varied_capacity(node_bits in 6u8..=16, count in 1usize..=20_000) {
            let config = SnowIDConfig::builder().node_bits(node_bits).unwrap().build();
            let generator = SnowID::with_config(1, config).unwrap();
            let ids: Vec<u64> = (0..count).map(|_| generator.generate()).collect();

            assert_unique_ids(&ids, ids.len());
            assert_ids_monotonic(&ids);
        }

        #[test]
        fn try_generate_batch_never_exceeds_requested_or_capacity(node_bits in 6u8..=16, batch_len in 1usize..=131_072) {
            let config = SnowIDConfig::builder().node_bits(node_bits).unwrap().build();
            let generator = SnowID::with_config(1, config).unwrap();
            let mut ids = vec![0u64; batch_len];

            let written = generator.try_generate_batch(&mut ids);

            prop_assert!(written <= batch_len);
            prop_assert!(written <= usize::from(generator.config.max_sequence_id()) + 1);
            if written > 0 {
                assert_unique_ids(&ids[..written], written);
                assert_ids_monotonic(&ids[..written]);
            }
        }

        #[test]
        fn recent_custom_epochs_preserve_component_bounds(node_bits in 6u8..=16, epoch_offset_ms in 0u64..=86_400_000) {
            let epoch = wall_clock_ms(0) - epoch_offset_ms;
            let config = SnowIDConfig::builder().node_bits(node_bits).unwrap().epoch(epoch).build();
            let generator = SnowID::with_config(1, config).unwrap();
            let id = generator.generate();
            let (timestamp, node, sequence) = generator.extract.decompose(id);

            prop_assert!(timestamp <= epoch_offset_ms + 10);
            prop_assert_eq!(node, 1);
            prop_assert!(sequence <= generator.config.max_sequence_id());
        }
    }
}