use crate::WireExpr;
use super::{canon::Canonizable, keyexpr};
use std::sync::Arc;
use std::{convert::TryFrom, str::FromStr};
#[derive(Clone, PartialEq, Eq, Hash, serde::Deserialize)]
#[serde(try_from = "String")]
pub struct OwnedKeyExpr(pub(crate) Arc<str>);
impl serde::Serialize for OwnedKeyExpr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.serialize(serializer)
}
}
impl OwnedKeyExpr {
pub fn new<T, E>(t: T) -> Result<Self, E>
where
Self: TryFrom<T, Error = E>,
{
Self::try_from(t)
}
pub fn autocanonize<T, E>(mut t: T) -> Result<Self, E>
where
Self: TryFrom<T, Error = E>,
T: Canonizable,
{
t.canonize();
Self::new(t)
}
pub unsafe fn from_string_unchecked(s: String) -> Self {
Self::from_boxed_string_unchecked(s.into_boxed_str())
}
pub unsafe fn from_boxed_string_unchecked(s: Box<str>) -> Self {
OwnedKeyExpr(s.into())
}
}
#[allow(clippy::suspicious_arithmetic_impl)]
impl std::ops::Div<&keyexpr> for OwnedKeyExpr {
type Output = Self;
fn div(self, rhs: &keyexpr) -> Self::Output {
&self / rhs
}
}
#[allow(clippy::suspicious_arithmetic_impl)]
impl std::ops::Div<&keyexpr> for &OwnedKeyExpr {
type Output = OwnedKeyExpr;
fn div(self, rhs: &keyexpr) -> Self::Output {
let s: String = [self.as_str(), "/", rhs.as_str()].concat();
OwnedKeyExpr::autocanonize(s).unwrap() }
}
#[test]
fn div() {
let a = OwnedKeyExpr::new("a").unwrap();
let b = OwnedKeyExpr::new("b").unwrap();
let k = a / &b;
assert_eq!(k.as_str(), "a/b")
}
impl std::fmt::Debug for OwnedKeyExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.as_ref().fmt(f)
}
}
impl std::fmt::Display for OwnedKeyExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.as_ref().fmt(f)
}
}
impl std::ops::Deref for OwnedKeyExpr {
type Target = keyexpr;
fn deref(&self) -> &Self::Target {
unsafe { keyexpr::from_str_unchecked(&self.0) }
}
}
impl AsRef<str> for OwnedKeyExpr {
fn as_ref(&self) -> &str {
&self.0
}
}
impl FromStr for OwnedKeyExpr {
type Err = zenoh_core::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::try_from(s.to_owned())
}
}
impl TryFrom<&str> for OwnedKeyExpr {
type Error = zenoh_core::Error;
fn try_from(s: &str) -> Result<Self, Self::Error> {
Self::try_from(s.to_owned())
}
}
impl TryFrom<String> for OwnedKeyExpr {
type Error = zenoh_core::Error;
fn try_from(value: String) -> Result<Self, Self::Error> {
<&keyexpr as TryFrom<&str>>::try_from(value.as_str())?;
Ok(Self(value.into()))
}
}
impl<'a> From<&'a keyexpr> for OwnedKeyExpr {
fn from(val: &'a keyexpr) -> Self {
OwnedKeyExpr(Arc::from(val.as_str()))
}
}
impl From<OwnedKeyExpr> for Arc<str> {
fn from(ke: OwnedKeyExpr) -> Self {
ke.0
}
}
impl From<OwnedKeyExpr> for String {
fn from(ke: OwnedKeyExpr) -> Self {
ke.as_str().to_owned()
}
}
impl<'a> From<&'a OwnedKeyExpr> for WireExpr<'a> {
fn from(val: &'a OwnedKeyExpr) -> Self {
WireExpr {
scope: 0,
suffix: std::borrow::Cow::Borrowed(val.as_str()),
}
}
}