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}