1use crate::error::ForceSyncError;
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct SyncKey {
8 tenant: String,
9 object_name: String,
10 external_id: String,
11}
12
13impl SyncKey {
14 pub fn new(
20 tenant: impl Into<String>,
21 object_name: impl Into<String>,
22 external_id: impl Into<String>,
23 ) -> Result<Self, ForceSyncError> {
24 let tenant = tenant.into();
25 let object_name = object_name.into();
26 let external_id = external_id.into();
27
28 if tenant.is_empty() {
29 return Err(ForceSyncError::EmptySyncKeyPart { part: "tenant" });
30 }
31
32 if object_name.is_empty() {
33 return Err(ForceSyncError::EmptySyncKeyPart {
34 part: "object_name",
35 });
36 }
37
38 if external_id.is_empty() {
39 return Err(ForceSyncError::EmptySyncKeyPart {
40 part: "external_id",
41 });
42 }
43
44 Ok(Self {
45 tenant,
46 object_name,
47 external_id,
48 })
49 }
50
51 #[must_use]
53 pub fn tenant(&self) -> &str {
54 &self.tenant
55 }
56
57 #[must_use]
59 pub fn object_name(&self) -> &str {
60 &self.object_name
61 }
62
63 #[must_use]
65 pub fn external_id(&self) -> &str {
66 &self.external_id
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::SyncKey;
73
74 #[test]
75 fn sync_key_requires_non_empty_parts() {
76 let Err(err) = SyncKey::new("", "Account", "abc") else {
77 panic!("empty tenant should fail");
78 };
79
80 assert!(err.to_string().contains("tenant"));
81 }
82}