kcl_lib/execution/
id_generator.rs

1//! A generator for ArtifactIds that can be stable across executions.
2
3use crate::execution::{ArtifactId, ModuleId};
4
5const NAMESPACE_KCL: uuid::Uuid = uuid::uuid!("8bda3118-75eb-58c7-a866-bef1dcb495e7");
6
7/// A generator for ArtifactIds that can be stable across executions.
8#[derive(Debug, Clone, Default, PartialEq)]
9pub struct IdGenerator {
10    module_id: Option<ModuleId>,
11    next_id: u64,
12}
13
14impl IdGenerator {
15    pub fn new(module_id: Option<ModuleId>) -> Self {
16        Self { module_id, next_id: 0 }
17    }
18
19    pub fn next_uuid(&mut self) -> uuid::Uuid {
20        let next_id = self.next_id;
21
22        let next = format!(
23            "{} {}",
24            self.module_id.map(|id| id.to_string()).unwrap_or("none".to_string()),
25            next_id
26        );
27        let next_uuid = uuid::Uuid::new_v5(&NAMESPACE_KCL, next.as_bytes());
28
29        self.next_id += 1;
30
31        next_uuid
32    }
33
34    pub fn next_artifact_id(&mut self) -> ArtifactId {
35        ArtifactId::new(self.next_uuid())
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn test_id_generator() {
45        let mut generator = IdGenerator::new(Some(ModuleId::default()));
46
47        let uuid1 = generator.next_uuid();
48        let uuid2 = generator.next_uuid();
49
50        assert_ne!(uuid1, uuid2);
51    }
52
53    #[test]
54    // Test that the same generator produces the same UUIDs.
55    fn test_id_generator_stable() {
56        let mut generator = IdGenerator::new(Some(ModuleId::default()));
57
58        let uuid1 = generator.next_uuid();
59        let uuid2 = generator.next_uuid();
60
61        let mut generator = IdGenerator::new(Some(ModuleId::default()));
62
63        let uuid3 = generator.next_uuid();
64        let uuid4 = generator.next_uuid();
65
66        assert_eq!(uuid1, uuid3);
67        assert_eq!(uuid2, uuid4);
68    }
69
70    #[test]
71    // Generate 20 uuids and make sure all are unique.
72    fn test_id_generator_unique() {
73        let mut generator = IdGenerator::new(Some(ModuleId::default()));
74
75        let mut uuids = Vec::new();
76
77        for _ in 0..20 {
78            uuids.push(generator.next_uuid());
79        }
80
81        for i in 0..uuids.len() {
82            for j in i + 1..uuids.len() {
83                assert_ne!(uuids[i], uuids[j]);
84            }
85        }
86    }
87}