Skip to main content

zenoh_protocol/core/
locator.rs

1//
2// Copyright (c) 2023 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//
14use alloc::{borrow::ToOwned, string::String};
15use core::{convert::TryFrom, fmt, hash::Hash, str::FromStr};
16
17use zenoh_result::{Error as ZError, ZResult};
18
19use super::endpoint::*;
20
21/// A string that respects the [`Locator`] canon form: `<proto>/<address>[?<metadata>]`.
22///
23/// `<metadata>` is of the form `<key1>=<value1>;...;<keyN>=<valueN>` where keys are alphabetically sorted.
24#[derive(Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
25#[serde(into = "String")]
26#[serde(try_from = "String")]
27pub struct Locator(pub(super) EndPoint);
28
29impl Locator {
30    pub fn new<A, B, C>(protocol: A, address: B, metadata: C) -> ZResult<Self>
31    where
32        A: AsRef<str>,
33        B: AsRef<str>,
34        C: AsRef<str>,
35    {
36        let ep = EndPoint::new(protocol, address, metadata, "")?;
37        Ok(Self(ep))
38    }
39
40    pub fn protocol(&self) -> Protocol<'_> {
41        self.0.protocol()
42    }
43
44    pub fn protocol_mut(&mut self) -> ProtocolMut<'_> {
45        self.0.protocol_mut()
46    }
47
48    pub fn address(&self) -> Address<'_> {
49        self.0.address()
50    }
51
52    pub fn address_mut(&mut self) -> AddressMut<'_> {
53        self.0.address_mut()
54    }
55
56    pub fn metadata(&self) -> Metadata<'_> {
57        self.0.metadata()
58    }
59
60    pub fn metadata_mut(&mut self) -> MetadataMut<'_> {
61        self.0.metadata_mut()
62    }
63
64    pub fn as_str(&self) -> &str {
65        self.0.as_str()
66    }
67
68    pub fn to_endpoint(&self) -> EndPoint {
69        self.0.clone()
70    }
71
72    /// Constructs an uninitialized empty Locator.
73    #[zenoh_macros::internal]
74    pub fn empty() -> Self {
75        Locator(EndPoint::empty())
76    }
77}
78
79impl From<EndPoint> for Locator {
80    fn from(mut val: EndPoint) -> Self {
81        if let Some(cidx) = val.inner.find(CONFIG_SEPARATOR) {
82            val.inner.truncate(cidx);
83        }
84        Locator(val)
85    }
86}
87
88impl TryFrom<&str> for Locator {
89    type Error = ZError;
90
91    fn try_from(s: &str) -> Result<Self, Self::Error> {
92        Self::try_from(s.to_owned())
93    }
94}
95
96impl From<Locator> for String {
97    fn from(val: Locator) -> Self {
98        val.0.into()
99    }
100}
101
102impl TryFrom<String> for Locator {
103    type Error = ZError;
104
105    fn try_from(s: String) -> Result<Self, Self::Error> {
106        let ep = EndPoint::try_from(s)?;
107        Ok(ep.into())
108    }
109}
110
111impl FromStr for Locator {
112    type Err = ZError;
113
114    fn from_str(s: &str) -> Result<Self, Self::Err> {
115        Self::try_from(s.to_owned())
116    }
117}
118
119impl fmt::Display for Locator {
120    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121        f.write_str(self.0.as_str())
122    }
123}
124
125impl fmt::Debug for Locator {
126    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127        write!(f, "{self}")
128    }
129}
130
131impl Locator {
132    #[cfg(feature = "test")]
133    #[doc(hidden)]
134    pub fn rand() -> Self {
135        EndPoint::rand().into()
136    }
137}