Skip to main content

valence_core/
reference.rs

1//! Reference placeholders for batch entity creation.
2
3use std::sync::{Arc, Mutex};
4
5use crate::RecordId;
6use uuid::Uuid;
7
8#[derive(Clone, Debug)]
9pub struct Reference<T> {
10    id: String,
11    resolved: Arc<Mutex<Option<RecordId>>>,
12    _phantom: std::marker::PhantomData<T>,
13}
14
15impl<T> Reference<T> {
16    pub fn new() -> Self {
17        Self {
18            id: format!("ref_{}", Uuid::new_v4()),
19            resolved: Arc::new(Mutex::new(None)),
20            _phantom: std::marker::PhantomData,
21        }
22    }
23
24    pub fn id(&self) -> &str {
25        &self.id
26    }
27
28    pub fn resolve(&self) -> Option<RecordId> {
29        self.resolved
30            .lock()
31            .unwrap_or_else(|poisoned| poisoned.into_inner())
32            .clone()
33    }
34
35    /// Store the resolved record id for this placeholder reference.
36    pub fn resolve_to(&self, id: RecordId) {
37        *self
38            .resolved
39            .lock()
40            .unwrap_or_else(|poisoned| poisoned.into_inner()) = Some(id);
41    }
42
43    pub fn is_resolved(&self) -> bool {
44        self.resolved
45            .lock()
46            .unwrap_or_else(|poisoned| poisoned.into_inner())
47            .is_some()
48    }
49}
50
51impl<T> Default for Reference<T> {
52    fn default() -> Self {
53        Self::new()
54    }
55}
56
57pub trait WithReference: Sized {
58    fn with_reference(self, reference: Reference<Self>) -> ReferencedEntity<Self> {
59        ReferencedEntity {
60            reference,
61            entity: self,
62        }
63    }
64}
65
66pub struct ReferencedEntity<T> {
67    pub(crate) reference: Reference<T>,
68    pub(crate) entity: T,
69}
70
71impl<T> ReferencedEntity<T> {
72    pub fn new(reference: Reference<T>, entity: T) -> Self {
73        Self { reference, entity }
74    }
75
76    pub fn reference(&self) -> &Reference<T> {
77        &self.reference
78    }
79
80    pub fn entity(&self) -> &T {
81        &self.entity
82    }
83
84    pub fn into_entity(self) -> T {
85        self.entity
86    }
87}