1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2024 Google LLC. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 use crate::__internal::{Private, SealedInternal}; 9 use crate::{ 10 AsView, IntoProxied, IntoView, ProtoBytes, ProtoStr, ProtoString, Proxied, Proxy, View, 11 ViewProxy, 12 }; 13 use paste::paste; 14 use std::cmp::PartialEq; 15 use std::ops::Deref; 16 17 macro_rules! impl_cord_types { 18 ($($t:ty, $vt:ty);*) => { 19 paste! { $( 20 #[derive(Debug)] 21 pub struct [< $t Cord>](Private); 22 23 #[derive(Debug)] 24 pub enum [< $t Cow>]<'a> { 25 Borrowed(View<'a, $t>), 26 Owned($t), 27 } 28 29 impl SealedInternal for [< $t Cord>] {} 30 31 impl<'msg> SealedInternal for [< $t Cow>]<'msg> {} 32 33 impl Proxied for [< $t Cord>] { 34 type View<'msg> = [< $t Cow>]<'msg>; 35 } 36 37 impl AsView for [< $t Cord>] { 38 type Proxied = Self; 39 fn as_view(&self) -> [< $t Cow>]<'_> { 40 unimplemented!("Proto Cord should never be constructed"); 41 } 42 } 43 44 impl<'msg> Proxy<'msg> for [< $t Cow>]<'msg> {} 45 46 impl<'msg> ViewProxy<'msg> for [< $t Cow>]<'msg> {} 47 48 impl<'msg> AsView for [< $t Cow>]<'msg> { 49 type Proxied = [< $t Cord>]; 50 51 fn as_view(&self) -> [< $t Cow>]<'_> { 52 match self { 53 [< $t Cow>]::Owned(owned) => [< $t Cow>]::Borrowed((*owned).as_view()), 54 [< $t Cow>]::Borrowed(borrowed) => [< $t Cow>]::Borrowed(borrowed), 55 } 56 } 57 } 58 59 impl<'msg> IntoView<'msg> for [< $t Cow>]<'msg> { 60 fn into_view<'shorter>(self) -> [< $t Cow>]<'shorter> 61 where 62 'msg: 'shorter, { 63 match self { 64 [< $t Cow>]::Owned(owned) => [< $t Cow>]::Owned(owned), 65 [< $t Cow>]::Borrowed(borrow) => [< $t Cow>]::Borrowed(borrow.into_view()), 66 } 67 } 68 } 69 70 impl IntoProxied<$t> for [< $t Cow>]<'_> { 71 fn into_proxied(self, _private: Private) -> $t { 72 match self { 73 [< $t Cow>]::Owned(owned) => owned, 74 [< $t Cow>]::Borrowed(borrowed) => borrowed.into_proxied(Private), 75 } 76 } 77 } 78 79 impl<'a> Deref for [< $t Cow>]<'a> { 80 type Target = $vt; 81 82 fn deref(&self) -> View<'_, $t> { 83 match self { 84 [< $t Cow>]::Borrowed(borrow) => borrow, 85 [< $t Cow>]::Owned(owned) => (*owned).as_view(), 86 } 87 } 88 } 89 90 impl AsRef<[u8]> for [< $t Cow>]<'_> { 91 fn as_ref(&self) -> &[u8] { 92 match self { 93 [< $t Cow>]::Borrowed(borrow) => borrow.as_ref(), 94 [< $t Cow>]::Owned(owned) => owned.as_ref(), 95 } 96 } 97 } 98 )* 99 } 100 } 101 } 102 103 impl_cord_types!( 104 ProtoString, ProtoStr; 105 ProtoBytes, [u8] 106 ); 107 108 macro_rules! impl_eq { 109 ($($t1:ty, $t2:ty);*) => { 110 paste! { $( 111 impl PartialEq<$t1> for $t2 { 112 fn eq(&self, rhs: &$t1) -> bool { 113 AsRef::<[u8]>::as_ref(self) == AsRef::<[u8]>::as_ref(rhs) 114 } 115 } 116 )* 117 } 118 } 119 } 120 121 impl_eq!( 122 ProtoStringCow<'_>, ProtoStringCow<'_>; 123 str, ProtoStringCow<'_>; 124 ProtoStringCow<'_>, str; 125 ProtoBytesCow<'_>, ProtoBytesCow<'_>; 126 [u8], ProtoBytesCow<'_>; 127 ProtoBytesCow<'_>, [u8] 128 ); 129