macro_rules! convert_stringy {
( $type:path, $trait:ident, $sealed:ident, $fail_msg:literal $(, $extra_bound:path )* ) => {
#[allow(unused)]
use std::str::FromStr;
impl Borrowable<$type> for $type {
fn as_ref(&self) -> &$type {
self
}
fn into_owned(self) -> $type {
self
}
}
impl Borrowable<$type> for &$type {
fn as_ref(&self) -> &$type {
&*self
}
fn into_owned(self) -> $type {
self.clone()
}
}
impl Borrowable<$type> for std::sync::Arc<$type> {
fn as_ref(&self) -> &$type {
&*self
}
fn into_owned(self) -> $type {
(*self).clone()
}
}
impl $trait for $type {}
impl<'a> $trait for &'a $type {}
impl<'a> $trait for std::sync::Arc<$type> {}
impl<'a> $trait for &std::sync::Arc<$type> {}
impl $trait for &str {}
impl $trait for String {}
impl $trait for &String {}
pub trait $sealed: Sized {
type Borrowable: Borrowable<$type> $(+ $extra_bound )*;
fn into_borrowable(self) -> Self::Borrowable;
fn into_owned(self) -> $type;
fn into_arc(self) -> std::sync::Arc<$type> {
std::sync::Arc::new(Self::into_owned(self))
}
}
impl $sealed for $type {
type Borrowable = $type;
fn into_borrowable(self) -> Self::Borrowable {
self
}
fn into_owned(self) -> $type {
self
}
}
impl $sealed for std::sync::Arc<$type> {
type Borrowable = std::sync::Arc<$type>;
fn into_borrowable(self) -> Self::Borrowable {
self
}
fn into_owned(self) -> $type {
(*self).clone()
}
fn into_arc(self) -> std::sync::Arc<$type>{
self
}
}
impl $sealed for &std::sync::Arc<$type> {
type Borrowable = std::sync::Arc<$type>;
fn into_borrowable(self) -> Self::Borrowable {
std::sync::Arc::clone(self)
}
fn into_owned(self) -> $type {
(**self).clone()
}
fn into_arc(self) -> std::sync::Arc<$type>{
std::sync::Arc::clone(self)
}
}
impl<'a> $sealed for &'a $type {
type Borrowable = &'a $type;
fn into_borrowable(self) -> Self::Borrowable {
self
}
fn into_owned(self) -> $type {
self.clone()
}
}
impl $sealed for &str {
type Borrowable = $type;
fn into_borrowable(self) -> Self::Borrowable {
<$type>::from_str(self).unwrap_or_else(|_| panic!(concat!($fail_msg, ": {}"), self))
}
fn into_owned(self) -> $type {
$sealed::into_borrowable(self)
}
}
impl $sealed for String {
type Borrowable = $type;
fn into_borrowable(self) -> Self::Borrowable {
$sealed::into_borrowable(self.as_str())
}
fn into_owned(self) -> $type {
$sealed::into_owned(self.as_str())
}
}
impl $sealed for &String {
type Borrowable = $type;
fn into_borrowable(self) -> Self::Borrowable {
$sealed::into_borrowable(self.as_str())
}
fn into_owned(self) -> $type {
$sealed::into_owned(self.as_str())
}
}
};
( @with_byte_impls, $type:path, $trait:ident, $sealed:ident, $fail_msg:literal $(, $extra_bound:path )* ) => {
convert_stringy!($type, $trait, $sealed, $fail_msg $(, $extra_bound )*);
impl $trait for &[u8] {}
impl $trait for Vec<u8> {}
impl $trait for &Vec<u8> {}
impl $sealed for &[u8] {
type Borrowable = $type;
fn into_borrowable(self) -> Self::Borrowable {
<$type>::try_from(self).unwrap_or_else(|_| panic!(concat!($fail_msg, ": {:?}"), self))
}
fn into_owned(self) -> $type {
$sealed::into_borrowable(self)
}
}
impl $sealed for Vec<u8> {
type Borrowable = $type;
fn into_borrowable(self) -> Self::Borrowable {
$sealed::into_borrowable(self.as_slice())
}
fn into_owned(self) -> $type {
$sealed::into_owned(self.as_slice())
}
}
impl $sealed for &Vec<u8> {
type Borrowable = $type;
fn into_borrowable(self) -> Self::Borrowable {
$sealed::into_borrowable(self.as_slice())
}
fn into_owned(self) -> $type {
$sealed::into_owned(self.as_slice())
}
}
};
}