reactive_graph_graph/instances/relations/
relation_instance_id.rs1use schemars::JsonSchema;
2use serde::Deserialize;
3use serde::Serialize;
4use std::cmp::Ordering;
5use std::fmt::Display;
6use std::fmt::Formatter;
7use typed_builder::TypedBuilder;
8use uuid::Uuid;
9
10use crate::NamespacedType;
11use crate::NamespacedTypeGetter;
12use crate::RelationInstanceTypeId;
13use crate::RelationTypeId;
14use crate::TypeDefinition;
15use crate::TypeDefinitionGetter;
16use crate::TypeIdType;
17
18pub static RELATION_INSTANCE_ID_SEPARATOR: &str = "--";
20
21#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema, TypedBuilder)]
23pub struct RelationInstanceId {
24 pub outbound_id: Uuid,
26
27 #[builder(setter(into))]
29 pub ty: RelationInstanceTypeId,
30
31 pub inbound_id: Uuid,
33}
34
35impl RelationInstanceId {
36 pub fn new<RIT: Into<RelationInstanceTypeId>>(outbound_id: Uuid, ty: RIT, inbound_id: Uuid) -> Self {
37 RelationInstanceId {
38 outbound_id,
39 ty: ty.into(),
40 inbound_id,
41 }
42 }
43
44 pub fn new_unique<RT: Into<RelationTypeId>>(outbound_id: Uuid, ty: RT, inbound_id: Uuid) -> Self {
45 RelationInstanceId {
46 outbound_id,
47 ty: RelationInstanceTypeId::new_unique_id(ty),
48 inbound_id,
49 }
50 }
51
52 pub fn new_unique_for_instance_id<RT: Into<RelationTypeId>>(outbound_id: Uuid, ty: RT, instance_id: String, inbound_id: Uuid) -> Self {
53 RelationInstanceId {
54 outbound_id,
55 ty: RelationInstanceTypeId::new_unique_for_instance_id(ty, instance_id),
56 inbound_id,
57 }
58 }
59
60 pub fn new_with_random_instance_id<RT: Into<RelationTypeId>>(outbound_id: Uuid, ty: RT, inbound_id: Uuid) -> Self {
61 RelationInstanceId {
62 outbound_id,
63 ty: RelationInstanceTypeId::new_with_random_instance_id(ty),
64 inbound_id,
65 }
66 }
67}
68
69impl NamespacedTypeGetter for RelationInstanceId {
70 fn namespace(&self) -> String {
71 self.ty.namespace()
72 }
73
74 fn type_name(&self) -> String {
76 self.ty.type_name()
77 }
78}
79
80impl TypeDefinitionGetter for RelationInstanceId {
81 fn type_definition(&self) -> TypeDefinition {
82 self.into()
83 }
84}
85
86impl PartialOrd<Self> for RelationInstanceId {
87 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
88 Some(self.cmp(other))
89 }
90}
91
92impl Ord for RelationInstanceId {
93 fn cmp(&self, other: &Self) -> Ordering {
94 match self.ty.cmp(&other.ty) {
95 Ordering::Less => Ordering::Less,
96 Ordering::Equal => match self.outbound_id.cmp(&other.outbound_id) {
97 Ordering::Less => Ordering::Less,
98 Ordering::Equal => self.inbound_id.cmp(&other.inbound_id),
99 Ordering::Greater => Ordering::Greater,
100 },
101 Ordering::Greater => Ordering::Greater,
102 }
103 }
104}
105
106impl From<&RelationInstanceId> for RelationInstanceId {
107 fn from(ty: &RelationInstanceId) -> Self {
108 ty.clone()
109 }
110}
111
112impl From<&RelationInstanceId> for TypeDefinition {
113 fn from(ty: &RelationInstanceId) -> Self {
114 TypeDefinition::new(TypeIdType::RelationType, ty.into())
115 }
116}
117
118impl From<&RelationInstanceId> for NamespacedType {
119 fn from(ty: &RelationInstanceId) -> Self {
120 NamespacedType::from(&ty.ty)
122 }
123}
124
125impl TryFrom<&String> for RelationInstanceId {
126 type Error = ();
127
128 fn try_from(s: &String) -> Result<Self, Self::Error> {
129 let mut s = s.splitn(3, &RELATION_INSTANCE_ID_SEPARATOR);
130 let outbound_id = s.next().ok_or(())?.try_into().map_err(|_| ())?;
131 let ty: RelationInstanceTypeId = s.next().ok_or(())?.to_string().try_into().map_err(|_| ())?;
132 let inbound_id = s.next().ok_or(())?.try_into().map_err(|_| ())?;
133 Ok(RelationInstanceId::new(outbound_id, ty, inbound_id))
134 }
135}
136
137impl Display for RelationInstanceId {
138 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
139 write!(f, "{}-[{}]->{}", self.outbound_id, &self.ty, self.inbound_id)
140 }
141}