zenoh_protocol_core/key_expr/
owned.rs

1//
2// Copyright (c) 2022 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::WireExpr;
16
17use super::{canon::Canonizable, keyexpr};
18use std::sync::Arc;
19use std::{convert::TryFrom, str::FromStr};
20
21/// A [`Arc<str>`] newtype that is statically known to be a valid key expression.
22///
23/// See [`keyexpr`](super::borrowed::keyexpr).
24#[derive(Clone, PartialEq, Eq, Hash, serde::Deserialize)]
25#[serde(try_from = "String")]
26pub struct OwnedKeyExpr(pub(crate) Arc<str>);
27impl serde::Serialize for OwnedKeyExpr {
28    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29    where
30        S: serde::Serializer,
31    {
32        self.0.serialize(serializer)
33    }
34}
35
36impl OwnedKeyExpr {
37    /// Equivalent to `<OwnedKeyExpr as TryFrom>::try_from(t)`.
38    ///
39    /// Will return an Err if `t` isn't a valid key expression.
40    /// Note that to be considered a valid key expression, a string MUST be canon.
41    ///
42    /// [`OwnedKeyExpr::autocanonize`] is an alternative constructor that will canonize the passed expression before constructing it.
43    pub fn new<T, E>(t: T) -> Result<Self, E>
44    where
45        Self: TryFrom<T, Error = E>,
46    {
47        Self::try_from(t)
48    }
49
50    /// Canonizes the passed value before returning it as an `OwnedKeyExpr`.
51    ///
52    /// Will return Err if the passed value isn't a valid key expression despite canonization.
53    pub fn autocanonize<T, E>(mut t: T) -> Result<Self, E>
54    where
55        Self: TryFrom<T, Error = E>,
56        T: Canonizable,
57    {
58        t.canonize();
59        Self::new(t)
60    }
61
62    /// Constructs an OwnedKeyExpr without checking [`keyexpr`]'s invariants
63    /// # Safety
64    /// Key Expressions must follow some rules to be accepted by a Zenoh network.
65    /// Messages addressed with invalid key expressions will be dropped.
66    pub unsafe fn from_string_unchecked(s: String) -> Self {
67        Self::from_boxed_string_unchecked(s.into_boxed_str())
68    }
69    /// Constructs an OwnedKeyExpr without checking [`keyexpr`]'s invariants
70    /// # Safety
71    /// Key Expressions must follow some rules to be accepted by a Zenoh network.
72    /// Messages addressed with invalid key expressions will be dropped.
73    pub unsafe fn from_boxed_string_unchecked(s: Box<str>) -> Self {
74        OwnedKeyExpr(s.into())
75    }
76}
77#[allow(clippy::suspicious_arithmetic_impl)]
78impl std::ops::Div<&keyexpr> for OwnedKeyExpr {
79    type Output = Self;
80    fn div(self, rhs: &keyexpr) -> Self::Output {
81        &self / rhs
82    }
83}
84#[allow(clippy::suspicious_arithmetic_impl)]
85impl std::ops::Div<&keyexpr> for &OwnedKeyExpr {
86    type Output = OwnedKeyExpr;
87    fn div(self, rhs: &keyexpr) -> Self::Output {
88        let s: String = [self.as_str(), "/", rhs.as_str()].concat();
89        OwnedKeyExpr::autocanonize(s).unwrap() // Joining 2 key expressions should always result in a canonizable string.
90    }
91}
92#[test]
93fn div() {
94    let a = OwnedKeyExpr::new("a").unwrap();
95    let b = OwnedKeyExpr::new("b").unwrap();
96    let k = a / &b;
97    assert_eq!(k.as_str(), "a/b")
98}
99impl std::fmt::Debug for OwnedKeyExpr {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        self.as_ref().fmt(f)
102    }
103}
104impl std::fmt::Display for OwnedKeyExpr {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        self.as_ref().fmt(f)
107    }
108}
109
110impl std::ops::Deref for OwnedKeyExpr {
111    type Target = keyexpr;
112    fn deref(&self) -> &Self::Target {
113        unsafe { keyexpr::from_str_unchecked(&self.0) }
114    }
115}
116impl AsRef<str> for OwnedKeyExpr {
117    fn as_ref(&self) -> &str {
118        &self.0
119    }
120}
121impl FromStr for OwnedKeyExpr {
122    type Err = zenoh_core::Error;
123    fn from_str(s: &str) -> Result<Self, Self::Err> {
124        Self::try_from(s.to_owned())
125    }
126}
127impl TryFrom<&str> for OwnedKeyExpr {
128    type Error = zenoh_core::Error;
129    fn try_from(s: &str) -> Result<Self, Self::Error> {
130        Self::try_from(s.to_owned())
131    }
132}
133impl TryFrom<String> for OwnedKeyExpr {
134    type Error = zenoh_core::Error;
135    fn try_from(value: String) -> Result<Self, Self::Error> {
136        <&keyexpr as TryFrom<&str>>::try_from(value.as_str())?;
137        Ok(Self(value.into()))
138    }
139}
140impl<'a> From<&'a keyexpr> for OwnedKeyExpr {
141    fn from(val: &'a keyexpr) -> Self {
142        OwnedKeyExpr(Arc::from(val.as_str()))
143    }
144}
145impl From<OwnedKeyExpr> for Arc<str> {
146    fn from(ke: OwnedKeyExpr) -> Self {
147        ke.0
148    }
149}
150impl From<OwnedKeyExpr> for String {
151    fn from(ke: OwnedKeyExpr) -> Self {
152        ke.as_str().to_owned()
153    }
154}
155
156impl<'a> From<&'a OwnedKeyExpr> for WireExpr<'a> {
157    fn from(val: &'a OwnedKeyExpr) -> Self {
158        WireExpr {
159            scope: 0,
160            suffix: std::borrow::Cow::Borrowed(val.as_str()),
161        }
162    }
163}