Skip to main content

open_timeline_core/
id.rs

1// SPDX-License-Identifier: MIT
2
3//!
4//! Functions for ID management (create a globally unique one, or check if it
5//! already exists)
6//!
7
8use uuid::Uuid;
9
10/// The OpenTimeline ID type is a UUIDv4
11#[rustfmt::skip]
12#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[derive(derive_more::Display, serde::Serialize, serde::Deserialize)]
14#[serde(transparent)]
15#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
16#[cfg_attr(feature = "sqlx", sqlx(transparent))]
17pub struct OpenTimelineId(Uuid);
18
19impl OpenTimelineId {
20    /// Create a new `OpenTimelineId`
21    pub fn new() -> Self {
22        debug!("Creating new OpenTimelineId");
23        Self(Uuid::new_v4())
24    }
25
26    /// Create an ID from a string if the string is a valid ID
27    pub fn from<S: ToString>(string: S) -> Result<Self, uuid::Error> {
28        let string = string.to_string();
29        Ok(Self(Uuid::parse_str(&string)?))
30    }
31}
32
33#[cfg(test)]
34mod test {
35    use super::*;
36
37    #[test]
38    fn test_id_deserialization() {
39        let uuid_str = r#""550e8400-e29b-41d4-a716-446655440000""#;
40        let id: OpenTimelineId = serde_json::from_str(uuid_str).expect("Failed to deserialize");
41        assert_eq!(
42            id,
43            OpenTimelineId(Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap())
44        );
45
46        // Remove a "0" from the end (should fail because not valid)
47        let uuid_str = r#""550e8400-e29b-41d4-a716-44665544000""#;
48        assert!(serde_json::from_str::<OpenTimelineId>(uuid_str).is_err());
49    }
50
51    #[test]
52    fn test_id_serialization() {
53        let id = OpenTimelineId(Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap());
54        let json = serde_json::to_string(&id).unwrap();
55        assert_eq!(json, r#""550e8400-e29b-41d4-a716-446655440000""#);
56        assert_eq!(id.to_string(), "550e8400-e29b-41d4-a716-446655440000");
57    }
58}