// Protocol Buffers - Google's data interchange format // Copyright 2024 Google LLC. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd use crate::__internal::{Private, SealedInternal}; use crate::{ AsView, IntoProxied, IntoView, ProtoBytes, ProtoStr, ProtoString, Proxied, Proxy, View, ViewProxy, }; use paste::paste; use std::cmp::PartialEq; use std::ops::Deref; macro_rules! impl_cord_types { ($($t:ty, $vt:ty);*) => { paste! { $( #[derive(Debug)] pub struct [< $t Cord>](Private); #[derive(Debug)] pub enum [< $t Cow>]<'a> { Borrowed(View<'a, $t>), Owned($t), } impl SealedInternal for [< $t Cord>] {} impl<'msg> SealedInternal for [< $t Cow>]<'msg> {} impl Proxied for [< $t Cord>] { type View<'msg> = [< $t Cow>]<'msg>; } impl AsView for [< $t Cord>] { type Proxied = Self; fn as_view(&self) -> [< $t Cow>]<'_> { unimplemented!("Proto Cord should never be constructed"); } } impl<'msg> Proxy<'msg> for [< $t Cow>]<'msg> {} impl<'msg> ViewProxy<'msg> for [< $t Cow>]<'msg> {} impl<'msg> AsView for [< $t Cow>]<'msg> { type Proxied = [< $t Cord>]; fn as_view(&self) -> [< $t Cow>]<'_> { match self { [< $t Cow>]::Owned(owned) => [< $t Cow>]::Borrowed((*owned).as_view()), [< $t Cow>]::Borrowed(borrowed) => [< $t Cow>]::Borrowed(borrowed), } } } impl<'msg> IntoView<'msg> for [< $t Cow>]<'msg> { fn into_view<'shorter>(self) -> [< $t Cow>]<'shorter> where 'msg: 'shorter, { match self { [< $t Cow>]::Owned(owned) => [< $t Cow>]::Owned(owned), [< $t Cow>]::Borrowed(borrow) => [< $t Cow>]::Borrowed(borrow.into_view()), } } } impl IntoProxied<$t> for [< $t Cow>]<'_> { fn into_proxied(self, _private: Private) -> $t { match self { [< $t Cow>]::Owned(owned) => owned, [< $t Cow>]::Borrowed(borrowed) => borrowed.into_proxied(Private), } } } impl<'a> Deref for [< $t Cow>]<'a> { type Target = $vt; fn deref(&self) -> View<'_, $t> { match self { [< $t Cow>]::Borrowed(borrow) => borrow, [< $t Cow>]::Owned(owned) => (*owned).as_view(), } } } impl AsRef<[u8]> for [< $t Cow>]<'_> { fn as_ref(&self) -> &[u8] { match self { [< $t Cow>]::Borrowed(borrow) => borrow.as_ref(), [< $t Cow>]::Owned(owned) => owned.as_ref(), } } } )* } } } impl_cord_types!( ProtoString, ProtoStr; ProtoBytes, [u8] ); macro_rules! impl_eq { ($($t1:ty, $t2:ty);*) => { paste! { $( impl PartialEq<$t1> for $t2 { fn eq(&self, rhs: &$t1) -> bool { AsRef::<[u8]>::as_ref(self) == AsRef::<[u8]>::as_ref(rhs) } } )* } } } impl_eq!( ProtoStringCow<'_>, ProtoStringCow<'_>; str, ProtoStringCow<'_>; ProtoStringCow<'_>, str; ProtoBytesCow<'_>, ProtoBytesCow<'_>; [u8], ProtoBytesCow<'_>; ProtoBytesCow<'_>, [u8] );