mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
Make any &T impl AsView if T impl AsView
And same for &mut T if T impl AsMut This matches the behavior of std::convert::AsRef which has similar blanket impls to this. PiperOrigin-RevId: 883287790
This commit is contained in:
parent
9b38d6d9a1
commit
d787869082
3 changed files with 125 additions and 1 deletions
|
|
@ -41,6 +41,9 @@ pub struct Private;
|
|||
/// traits to support trait objects.
|
||||
pub trait SealedInternal: Sized {}
|
||||
|
||||
impl<T: SealedInternal> SealedInternal for &T {}
|
||||
impl<T: SealedInternal> SealedInternal for &mut T {}
|
||||
|
||||
/// A trait used by the proto_eq() gtest macro.
|
||||
pub trait MatcherEq: SealedInternal + Debug {
|
||||
fn matches(&self, o: &Self) -> bool;
|
||||
|
|
|
|||
|
|
@ -115,6 +115,20 @@ pub trait AsView: SealedInternal {
|
|||
fn as_view(&self) -> View<'_, Self::Proxied>;
|
||||
}
|
||||
|
||||
impl<T: Proxied> AsView for &T {
|
||||
type Proxied = T::Proxied;
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
(**self).as_view()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Proxied> AsView for &mut T {
|
||||
type Proxied = T::Proxied;
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
(**self).as_view()
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to turn another 'borrow' into a view proxy.
|
||||
///
|
||||
/// On a mut proxy this borrows to a View (semantically matching turning a `&mut
|
||||
|
|
@ -153,6 +167,24 @@ pub trait IntoView<'msg>: SealedInternal + AsView {
|
|||
'msg: 'shorter;
|
||||
}
|
||||
|
||||
impl<'msg, T: Proxied> IntoView<'msg> for &'msg T {
|
||||
fn into_view<'shorter>(self) -> View<'shorter, T>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
{
|
||||
(*self).as_view()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'msg, T: Proxied> IntoView<'msg> for &'msg mut T {
|
||||
fn into_view<'shorter>(self) -> View<'shorter, T>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
{
|
||||
(*self).as_view()
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to semantically do a cheap "to-mut-reference" conversion. This is
|
||||
/// implemented on both owned `Proxied` types as well as mut proxy types.
|
||||
///
|
||||
|
|
@ -164,6 +196,13 @@ pub trait AsMut: SealedInternal + AsView<Proxied = Self::MutProxied> {
|
|||
fn as_mut(&mut self) -> Mut<'_, Self::MutProxied>;
|
||||
}
|
||||
|
||||
impl<T: MutProxied> AsMut for &mut T {
|
||||
type MutProxied = T::MutProxied;
|
||||
fn as_mut(&mut self) -> Mut<'_, Self::MutProxied> {
|
||||
(*self).as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to turn another 'borrow' into a mut proxy.
|
||||
///
|
||||
/// On a mut proxy this will behave as a reborrow into a shorter lifetime
|
||||
|
|
@ -196,6 +235,15 @@ pub trait IntoMut<'msg>: SealedInternal + AsMut {
|
|||
'msg: 'shorter;
|
||||
}
|
||||
|
||||
impl<'msg, T: MutProxied> IntoMut<'msg> for &'msg mut T {
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, T>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
{
|
||||
(*self).as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
/// A value to `Proxied`-value conversion that consumes the input value.
|
||||
///
|
||||
/// All setter functions accept types that implement `IntoProxied`. The purpose
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use protos::*;
|
|||
use googletest::prelude::*;
|
||||
use protobuf::prelude::*;
|
||||
|
||||
use protobuf::{AsMut, AsView, Message};
|
||||
use protobuf::{AsMut, AsView, IntoMut, IntoView, Message};
|
||||
use unittest_rust_proto::TestAllTypes;
|
||||
|
||||
fn f<M: Message, T: AsView<Proxied = M>>(msg_view: T) -> usize {
|
||||
|
|
@ -73,3 +73,76 @@ fn msg_used_generically_struct_test() {
|
|||
let empty: &[u8] = &[];
|
||||
expect_that!(proto_send_msg.encode(), eq(empty));
|
||||
}
|
||||
|
||||
#[gtest]
|
||||
fn as_view_serialize_test() {
|
||||
fn as_view_serialize<M: Message, T: AsView<Proxied = M>>(msg_view: T) -> usize {
|
||||
msg_view.as_view().serialize().unwrap().len()
|
||||
}
|
||||
let mut msg = TestAllTypes::new();
|
||||
expect_that!(as_view_serialize(msg.as_view()), eq(0));
|
||||
expect_that!(as_view_serialize(&msg), eq(0));
|
||||
expect_that!(as_view_serialize(&mut msg), eq(0));
|
||||
expect_that!(as_view_serialize(msg), eq(0));
|
||||
}
|
||||
|
||||
#[gtest]
|
||||
fn into_view_serialize_test() {
|
||||
fn into_view_serialize<'a, M: Message, T: IntoView<'a, Proxied = M>>(msg_view: T) -> usize {
|
||||
msg_view.into_view().serialize().unwrap().len()
|
||||
}
|
||||
let mut msg = TestAllTypes::new();
|
||||
expect_that!(into_view_serialize(msg.as_view()), eq(0));
|
||||
expect_that!(into_view_serialize(&msg), eq(0));
|
||||
expect_that!(into_view_serialize(&mut msg), eq(0));
|
||||
}
|
||||
|
||||
#[gtest]
|
||||
fn as_mut_clear_test() {
|
||||
fn as_mut_clear<M: Message, T: AsMut<MutProxied = M>>(mut msg_mut: T) {
|
||||
msg_mut.as_mut().clear();
|
||||
}
|
||||
|
||||
{
|
||||
let mut msg = TestAllTypes::new();
|
||||
msg.set_optional_int32(123);
|
||||
expect_that!(msg.has_optional_int32(), eq(true));
|
||||
as_mut_clear(msg.as_mut());
|
||||
expect_that!(msg.has_optional_int32(), eq(false));
|
||||
}
|
||||
{
|
||||
let mut msg = TestAllTypes::new();
|
||||
msg.set_optional_int32(123);
|
||||
expect_that!(msg.has_optional_int32(), eq(true));
|
||||
as_mut_clear(&mut msg);
|
||||
expect_that!(msg.has_optional_int32(), eq(false));
|
||||
}
|
||||
{
|
||||
let mut msg = TestAllTypes::new();
|
||||
msg.set_optional_int32(123);
|
||||
expect_that!(msg.has_optional_int32(), eq(true));
|
||||
as_mut_clear(msg); // msg itself is AsMut but this consumes the msg.
|
||||
}
|
||||
}
|
||||
|
||||
#[gtest]
|
||||
fn into_mut_clear_test() {
|
||||
fn into_mut_clear<'a, M: Message, T: IntoMut<'a, MutProxied = M>>(msg_mut: T) {
|
||||
msg_mut.into_mut().clear();
|
||||
}
|
||||
|
||||
{
|
||||
let mut msg = TestAllTypes::new();
|
||||
msg.set_optional_int32(123);
|
||||
expect_that!(msg.has_optional_int32(), eq(true));
|
||||
into_mut_clear(msg.as_mut());
|
||||
expect_that!(msg.has_optional_int32(), eq(false));
|
||||
}
|
||||
{
|
||||
let mut msg = TestAllTypes::new();
|
||||
msg.set_optional_int32(123);
|
||||
expect_that!(msg.has_optional_int32(), eq(true));
|
||||
into_mut_clear(&mut msg);
|
||||
expect_that!(msg.has_optional_int32(), eq(false));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue