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
73impl From<EndPoint> for Locator {
74    fn from(mut val: EndPoint) -> Self {
75        if let Some(cidx) = val.inner.find(CONFIG_SEPARATOR) {
76            val.inner.truncate(cidx);
77        }
78        Locator(val)
79    }
80}
81
82impl TryFrom<&str> for Locator {
83    type Error = ZError;
84
85    fn try_from(s: &str) -> Result<Self, Self::Error> {
86        Self::try_from(s.to_owned())
87    }
88}
89
90impl From<Locator> for String {
91    fn from(val: Locator) -> Self {
92        val.0.into()
93    }
94}
95
96impl TryFrom<String> for Locator {
97    type Error = ZError;
98
99    fn try_from(s: String) -> Result<Self, Self::Error> {
100        let ep = EndPoint::try_from(s)?;
101        Ok(ep.into())
102    }
103}
104
105impl FromStr for Locator {
106    type Err = ZError;
107
108    fn from_str(s: &str) -> Result<Self, Self::Err> {
109        Self::try_from(s.to_owned())
110    }
111}
112
113impl fmt::Display for Locator {
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        f.write_str(self.0.as_str())
116    }
117}
118
119impl fmt::Debug for Locator {
120    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121        write!(f, "{}", self)
122    }
123}
124
125impl Locator {
126    #[cfg(feature = "test")]
127    pub fn rand() -> Self {
128        EndPoint::rand().into()
129    }
130}