zenoh_flow_commons/identifiers.rs
1//
2// Copyright (c) 2021 - 2024 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12// ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14
15use crate::deserialize::deserialize_id;
16use std::ops::Deref;
17use std::sync::Arc;
18use std::{fmt::Display, str::FromStr};
19
20use anyhow::anyhow;
21use serde::{Deserialize, Serialize};
22use uuid::Uuid;
23use zenoh_protocol::core::ZenohId;
24
25/// A `NodeId` uniquely identifies a Node within a data flow.
26///
27/// A `NodeId` additionally satisfies the following constraints:
28/// - it does *not* contain any of the symbols: * # $ ? >
29/// - it is a valid [canonical Zenoh key expression](zenoh_keyexpr::OwnedKeyExpr::autocanonize).
30///
31/// # Performance
32///
33/// A `NodeId` is encapsulated in an [Arc] rendering clone operations inexpensive.
34#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone, Hash)]
35pub struct NodeId(#[serde(deserialize_with = "deserialize_id")] Arc<str>);
36
37impl Deref for NodeId {
38 type Target = Arc<str>;
39
40 fn deref(&self) -> &Self::Target {
41 &self.0
42 }
43}
44
45impl Display for NodeId {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 write!(f, "{}", &self.0)
48 }
49}
50
51impl From<String> for NodeId {
52 fn from(value: String) -> Self {
53 Self(value.into())
54 }
55}
56
57impl From<&str> for NodeId {
58 fn from(value: &str) -> Self {
59 Self(value.into())
60 }
61}
62
63/// A `PortId` identifies an `Input` or an `Output` of a Node.
64///
65/// A `PortId` additionally satisfies the following constraints:
66/// - it does *not* contain any of the symbols: * # $ ? >
67/// - it is a valid [canonical Zenoh key expression](zenoh_keyexpr::OwnedKeyExpr::autocanonize).
68///
69/// # Uniqueness
70///
71/// A `PortId` does not need to be unique within a data flow. It should only be unique among the ports of the same node
72/// and of the same type (i.e. `Input` or `Output`).
73/// For instance, a node can have an `Input` and an `Output` with the same `PortId`.
74///
75/// # Performance
76///
77/// A `PortId` is encapsulated in an [Arc] rendering clone operations inexpensive.
78#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
79pub struct PortId(#[serde(deserialize_with = "deserialize_id")] Arc<str>);
80
81impl Deref for PortId {
82 type Target = Arc<str>;
83
84 fn deref(&self) -> &Self::Target {
85 &self.0
86 }
87}
88
89impl Display for PortId {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 write!(f, "{}", &self.0)
92 }
93}
94
95impl From<String> for PortId {
96 fn from(value: String) -> Self {
97 Self(value.into())
98 }
99}
100
101impl From<&str> for PortId {
102 fn from(value: &str) -> Self {
103 Self(value.into())
104 }
105}
106
107/// A `RuntimeId` uniquely identifies a Zenoh-Flow runtime within a Zenoh network.
108///
109/// The `RuntimeId` structure simply wraps a [ZenohId]. Similar to a Uuid, this identifier is (with a high probability)
110/// guaranteed to be unique within your infrastructure.
111///
112/// A Zenoh-Flow runtime will, by default, reuse the [ZenohId] of the Zenoh
113/// [session](https://docs.rs/zenoh/0.10.1-rc/zenoh/struct.Session.html) it will create to connect to the Zenoh network.
114#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize, Default)]
115#[repr(transparent)]
116pub struct RuntimeId(ZenohId);
117
118impl RuntimeId {
119 /// Generate a new random identifier, guaranteed (with a high probability) to be unique.
120 ///
121 /// This internally calls [ZenohId::rand].
122 pub fn rand() -> Self {
123 Self(ZenohId::rand())
124 }
125}
126
127impl Display for RuntimeId {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 write!(f, "{}", &self.0)
130 }
131}
132
133impl Deref for RuntimeId {
134 type Target = ZenohId;
135
136 fn deref(&self) -> &Self::Target {
137 &self.0
138 }
139}
140
141impl From<ZenohId> for RuntimeId {
142 fn from(value: ZenohId) -> Self {
143 Self(value)
144 }
145}
146
147impl FromStr for RuntimeId {
148 type Err = anyhow::Error;
149
150 fn from_str(s: &str) -> Result<Self, Self::Err> {
151 Ok(ZenohId::from_str(s)
152 .map_err(|e| anyhow!("Failed to parse < {} > as a valid ZenohId:\n{:?}", s, e))?
153 .into())
154 }
155}
156
157/// An `InstanceId` uniquely identifies a data flow instance.
158///
159/// A data flow instance is created every time Zenoh-Flow is tasked to run a data flow. Each instance of the same data
160/// flow will have a different `InstanceId`.
161///
162/// Internally, it uses a [Uuid v4](uuid::Uuid::new_v4) that it wraps inside an [Arc]. This allows for inexpensive
163/// `clone` operations.
164#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
165pub struct InstanceId(Arc<Uuid>);
166
167impl Display for InstanceId {
168 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169 write!(f, "{}", &self.0)
170 }
171}
172
173impl From<Uuid> for InstanceId {
174 fn from(value: Uuid) -> Self {
175 Self(Arc::new(value))
176 }
177}
178
179impl Deref for InstanceId {
180 type Target = Uuid;
181
182 fn deref(&self) -> &Self::Target {
183 &self.0
184 }
185}