Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
527 lines
16 KiB
527 lines
16 KiB
// Protocol Buffers - Google's data interchange format |
|
// Copyright 2023 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 std::fmt::{self, Debug}; |
|
use std::iter; |
|
use std::iter::FusedIterator; |
|
/// Repeated scalar fields are implemented around the runtime-specific |
|
/// `RepeatedField` struct. `RepeatedField` stores an opaque pointer to the |
|
/// runtime-specific representation of a repeated scalar (`upb_Array*` on upb, |
|
/// and `RepeatedField<T>*` on cpp). |
|
use std::marker::PhantomData; |
|
|
|
use crate::{ |
|
Mut, MutProxy, Proxied, SettableValue, View, ViewProxy, |
|
__internal::Private, |
|
__runtime::{InnerRepeated, InnerRepeatedMut, RawRepeatedField}, |
|
}; |
|
|
|
/// Views the elements in a `repeated` field of `T`. |
|
#[repr(transparent)] |
|
pub struct RepeatedView<'msg, T: ?Sized> { |
|
// This does not need to carry an arena in upb, so it can be just the raw repeated field |
|
raw: RawRepeatedField, |
|
_phantom: PhantomData<&'msg T>, |
|
} |
|
|
|
impl<'msg, T: ?Sized> Copy for RepeatedView<'msg, T> {} |
|
impl<'msg, T: ?Sized> Clone for RepeatedView<'msg, T> { |
|
fn clone(&self) -> Self { |
|
*self |
|
} |
|
} |
|
|
|
unsafe impl<'msg, T: ?Sized> Sync for RepeatedView<'msg, T> {} |
|
unsafe impl<'msg, T: ?Sized> Send for RepeatedView<'msg, T> {} |
|
|
|
impl<'msg, T: ?Sized> Debug for RepeatedView<'msg, T> { |
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
f.debug_struct("RepeatedView").field("raw", &self.raw).finish() |
|
} |
|
} |
|
|
|
/// Mutates the elements in a `repeated` field of `T`. |
|
pub struct RepeatedMut<'msg, T: ?Sized> { |
|
pub(crate) inner: InnerRepeatedMut<'msg>, |
|
_phantom: PhantomData<&'msg mut T>, |
|
} |
|
|
|
unsafe impl<'msg, T: ?Sized> Sync for RepeatedMut<'msg, T> {} |
|
|
|
impl<'msg, T: ?Sized> Debug for RepeatedMut<'msg, T> { |
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
f.debug_struct("RepeatedMut").field("raw", &self.inner.raw).finish() |
|
} |
|
} |
|
|
|
#[doc(hidden)] |
|
impl<'msg, T: ?Sized> RepeatedView<'msg, T> { |
|
#[doc(hidden)] |
|
pub fn as_raw(&self, _private: Private) -> RawRepeatedField { |
|
self.raw |
|
} |
|
|
|
/// # Safety |
|
/// - `inner` must be valid to read from for `'msg` |
|
#[doc(hidden)] |
|
pub unsafe fn from_raw(_private: Private, raw: RawRepeatedField) -> Self { |
|
Self { raw, _phantom: PhantomData } |
|
} |
|
} |
|
|
|
impl<'msg, T> RepeatedView<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'msg, |
|
{ |
|
/// Gets the length of the repeated field. |
|
pub fn len(&self) -> usize { |
|
T::repeated_len(*self) |
|
} |
|
|
|
/// Returns true if the repeated field has no values. |
|
pub fn is_empty(&self) -> bool { |
|
self.len() == 0 |
|
} |
|
|
|
/// Gets the value at `index`. |
|
/// |
|
/// Returns `None` if `index > len`. |
|
pub fn get(self, index: usize) -> Option<View<'msg, T>> { |
|
if index >= self.len() { |
|
return None; |
|
} |
|
// SAFETY: `index` has been checked to be in-bounds |
|
Some(unsafe { self.get_unchecked(index) }) |
|
} |
|
|
|
/// Gets the value at `index` without bounds-checking. |
|
/// |
|
/// # Safety |
|
/// Undefined behavior if `index >= len` |
|
pub unsafe fn get_unchecked(self, index: usize) -> View<'msg, T> { |
|
// SAFETY: in-bounds as promised |
|
unsafe { T::repeated_get_unchecked(self, index) } |
|
} |
|
|
|
/// Iterates over the values in the repeated field. |
|
pub fn iter(self) -> RepeatedIter<'msg, T> { |
|
self.into_iter() |
|
} |
|
} |
|
|
|
#[doc(hidden)] |
|
impl<'msg, T: ?Sized> RepeatedMut<'msg, T> { |
|
/// # Safety |
|
/// - `inner` must be valid to read and write from for `'msg` |
|
/// - There must be no aliasing references or mutations on the same |
|
/// underlying object. |
|
#[doc(hidden)] |
|
pub unsafe fn from_inner(_private: Private, inner: InnerRepeatedMut<'msg>) -> Self { |
|
Self { inner, _phantom: PhantomData } |
|
} |
|
|
|
#[doc(hidden)] |
|
pub fn as_raw(&mut self, _private: Private) -> RawRepeatedField { |
|
self.inner.raw |
|
} |
|
} |
|
|
|
impl<'msg, T> RepeatedMut<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'msg, |
|
{ |
|
/// Gets the length of the repeated field. |
|
pub fn len(&self) -> usize { |
|
self.as_view().len() |
|
} |
|
|
|
/// Returns true if the repeated field has no values. |
|
pub fn is_empty(&self) -> bool { |
|
self.len() == 0 |
|
} |
|
|
|
/// Gets the value at `index`. |
|
/// |
|
/// Returns `None` if `index > len`. |
|
pub fn get(&self, index: usize) -> Option<View<T>> { |
|
self.as_view().get(index) |
|
} |
|
|
|
/// Gets the value at `index` without bounds-checking. |
|
/// |
|
/// # Safety |
|
/// Undefined behavior if `index >= len` |
|
pub unsafe fn get_unchecked(&self, index: usize) -> View<T> { |
|
// SAFETY: in-bounds as promised |
|
unsafe { self.as_view().get_unchecked(index) } |
|
} |
|
|
|
/// Appends `val` to the end of the repeated field. |
|
pub fn push(&mut self, val: View<T>) { |
|
// TODO: b/320936046 - Use SettableValue instead of View for added ergonomics. |
|
T::repeated_push(self.as_mut(), val); |
|
} |
|
|
|
/// Sets the value at `index` to the value `val`. |
|
/// |
|
/// # Panics |
|
/// Panics if `index >= len` |
|
pub fn set(&mut self, index: usize, val: View<T>) { |
|
let len = self.len(); |
|
if index >= len { |
|
panic!("index {index} >= repeated len {len}"); |
|
} |
|
// TODO: b/320936046 - Use SettableValue instead of View for added ergonomics. |
|
// SAFETY: `index` has been checked to be in-bounds. |
|
unsafe { self.set_unchecked(index, val) } |
|
} |
|
|
|
/// Sets the value at `index` to the value `val`. |
|
/// |
|
/// # Safety |
|
/// Undefined behavior if `index >= len` |
|
pub unsafe fn set_unchecked(&mut self, index: usize, val: View<T>) { |
|
// TODO: b/320936046 - Use SettableValue instead of View for added ergonomics. |
|
// SAFETY: `index` is in-bounds as promised by the caller. |
|
unsafe { T::repeated_set_unchecked(self.as_mut(), index, val) } |
|
} |
|
|
|
/// Iterates over the values in the repeated field. |
|
pub fn iter(&self) -> RepeatedIter<T> { |
|
self.as_view().into_iter() |
|
} |
|
|
|
/// Copies from the `src` repeated field into this one. |
|
/// |
|
/// Also provided by [`MutProxy::set`]. |
|
pub fn copy_from(&mut self, src: RepeatedView<'_, T>) { |
|
T::repeated_copy_from(src, self.as_mut()) |
|
} |
|
|
|
/// Clears the repeated field. |
|
pub fn clear(&mut self) { |
|
T::repeated_clear(self.as_mut()) |
|
} |
|
} |
|
|
|
/// Types that can appear in a `Repeated<T>`. |
|
/// |
|
/// This trait is implemented by generated code to communicate how the proxied |
|
/// type can be manipulated for a repeated field. |
|
/// |
|
/// Scalars and messages implement `ProxiedInRepeated`. |
|
/// |
|
/// # Safety |
|
/// - It must be sound to call `*_unchecked*(x)` with an `index` less than |
|
/// `repeated_len(x)`. |
|
pub unsafe trait ProxiedInRepeated: Proxied { |
|
/// Constructs a new owned `Repeated` field. |
|
#[doc(hidden)] |
|
fn repeated_new(_private: Private) -> Repeated<Self> { |
|
unimplemented!("not required") |
|
} |
|
|
|
/// Frees the repeated field in-place, for use in `Drop`. |
|
/// |
|
/// # Safety |
|
/// - After `repeated_free`, no other methods on the input are safe to call. |
|
#[doc(hidden)] |
|
unsafe fn repeated_free(_private: Private, _repeated: &mut Repeated<Self>) { |
|
unimplemented!("not required") |
|
} |
|
|
|
/// Gets the length of the repeated field. |
|
fn repeated_len(repeated: View<Repeated<Self>>) -> usize; |
|
|
|
/// Appends a new element to the end of the repeated field. |
|
fn repeated_push(repeated: Mut<Repeated<Self>>, val: View<Self>); |
|
|
|
/// Clears the repeated field of elements. |
|
fn repeated_clear(repeated: Mut<Repeated<Self>>); |
|
|
|
/// # Safety |
|
/// `index` must be less than `Self::repeated_len(repeated)` |
|
unsafe fn repeated_get_unchecked(repeated: View<Repeated<Self>>, index: usize) -> View<Self>; |
|
|
|
/// # Safety |
|
/// `index` must be less than `Self::repeated_len(repeated)` |
|
unsafe fn repeated_set_unchecked(repeated: Mut<Repeated<Self>>, index: usize, val: View<Self>); |
|
|
|
/// Copies the values in the `src` repeated field into `dest`. |
|
fn repeated_copy_from(src: View<Repeated<Self>>, dest: Mut<Repeated<Self>>); |
|
} |
|
|
|
/// An iterator over the values inside of a [`View<Repeated<T>>`](RepeatedView). |
|
pub struct RepeatedIter<'msg, T: ?Sized> { |
|
view: RepeatedView<'msg, T>, |
|
current_index: usize, |
|
} |
|
|
|
impl<'msg, T: ?Sized> Debug for RepeatedIter<'msg, T> { |
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
f.debug_struct("RepeatedIter") |
|
.field("view", &self.view) |
|
.field("current_index", &self.current_index) |
|
.finish() |
|
} |
|
} |
|
|
|
/// A `repeated` field of `T`, used as the owned target for `Proxied`. |
|
/// |
|
/// Users will generally write [`View<Repeated<T>>`](RepeatedView) or |
|
/// [`Mut<Repeated<T>>`](RepeatedMut) to access the repeated elements |
|
pub struct Repeated<T: ?Sized + ProxiedInRepeated> { |
|
inner: InnerRepeated, |
|
_phantom: PhantomData<T>, |
|
} |
|
|
|
impl<T: ?Sized + ProxiedInRepeated> Repeated<T> { |
|
pub fn new() -> Self { |
|
T::repeated_new(Private) |
|
} |
|
|
|
pub(crate) fn from_inner(inner: InnerRepeated) -> Self { |
|
Self { inner, _phantom: PhantomData } |
|
} |
|
|
|
pub(crate) fn as_mut(&mut self) -> RepeatedMut<'_, T> { |
|
RepeatedMut { inner: self.inner.as_mut(), _phantom: PhantomData } |
|
} |
|
} |
|
|
|
impl<T: ?Sized + ProxiedInRepeated> Default for Repeated<T> { |
|
fn default() -> Self { |
|
Repeated::new() |
|
} |
|
} |
|
|
|
impl<T: ?Sized + ProxiedInRepeated> Drop for Repeated<T> { |
|
fn drop(&mut self) { |
|
// SAFETY: only called once |
|
unsafe { T::repeated_free(Private, self) } |
|
} |
|
} |
|
|
|
// SAFETY: `Repeated` does not allow for shared mutability. |
|
unsafe impl<T: ProxiedInRepeated> Sync for Repeated<T> {} |
|
|
|
impl<T> Proxied for Repeated<T> |
|
where |
|
T: ProxiedInRepeated + ?Sized, |
|
{ |
|
type View<'msg> = RepeatedView<'msg, T> where Repeated<T>: 'msg; |
|
type Mut<'msg> = RepeatedMut<'msg, T> where Repeated<T>: 'msg; |
|
} |
|
|
|
impl<'msg, T> ViewProxy<'msg> for RepeatedView<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'msg, |
|
{ |
|
type Proxied = Repeated<T>; |
|
|
|
fn as_view(&self) -> View<'_, Self::Proxied> { |
|
*self |
|
} |
|
|
|
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> |
|
where |
|
'msg: 'shorter, |
|
{ |
|
RepeatedView { raw: self.raw, _phantom: PhantomData } |
|
} |
|
} |
|
|
|
impl<'msg, T> ViewProxy<'msg> for RepeatedMut<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'msg, |
|
{ |
|
type Proxied = Repeated<T>; |
|
|
|
fn as_view(&self) -> View<'_, Self::Proxied> { |
|
RepeatedView { raw: self.inner.raw, _phantom: PhantomData } |
|
} |
|
|
|
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> |
|
where |
|
'msg: 'shorter, |
|
{ |
|
RepeatedView { raw: self.inner.raw, _phantom: PhantomData } |
|
} |
|
} |
|
|
|
impl<'msg, T> MutProxy<'msg> for RepeatedMut<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'msg, |
|
{ |
|
fn as_mut(&mut self) -> Mut<'_, Self::Proxied> { |
|
RepeatedMut { inner: self.inner, _phantom: PhantomData } |
|
} |
|
|
|
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied> |
|
where |
|
'msg: 'shorter, |
|
{ |
|
RepeatedMut { inner: self.inner, _phantom: PhantomData } |
|
} |
|
} |
|
|
|
impl<'msg, T> SettableValue<Repeated<T>> for RepeatedView<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'msg, |
|
{ |
|
fn set_on<'b>(self, _private: Private, mutator: Mut<'b, Repeated<T>>) |
|
where |
|
Repeated<T>: 'b, |
|
{ |
|
T::repeated_copy_from(self, mutator) |
|
} |
|
} |
|
|
|
impl<'msg, T> iter::Iterator for RepeatedIter<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'msg, |
|
{ |
|
type Item = View<'msg, T>; |
|
|
|
fn next(&mut self) -> Option<Self::Item> { |
|
let val = self.view.get(self.current_index); |
|
if val.is_some() { |
|
self.current_index += 1; |
|
} |
|
val |
|
} |
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) { |
|
let len = self.len(); |
|
(len, Some(len)) |
|
} |
|
} |
|
|
|
impl<'msg, T: ?Sized + ProxiedInRepeated> ExactSizeIterator for RepeatedIter<'msg, T> { |
|
fn len(&self) -> usize { |
|
self.view.len() - self.current_index |
|
} |
|
} |
|
|
|
// TODO: impl DoubleEndedIterator |
|
impl<'msg, T: ?Sized + ProxiedInRepeated> FusedIterator for RepeatedIter<'msg, T> {} |
|
|
|
impl<'msg, T> iter::IntoIterator for RepeatedView<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'msg, |
|
{ |
|
type Item = View<'msg, T>; |
|
type IntoIter = RepeatedIter<'msg, T>; |
|
|
|
fn into_iter(self) -> Self::IntoIter { |
|
RepeatedIter { view: self, current_index: 0 } |
|
} |
|
} |
|
|
|
impl<'msg, T> iter::IntoIterator for &'_ RepeatedView<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'msg, |
|
{ |
|
type Item = View<'msg, T>; |
|
type IntoIter = RepeatedIter<'msg, T>; |
|
|
|
fn into_iter(self) -> Self::IntoIter { |
|
RepeatedIter { view: *self, current_index: 0 } |
|
} |
|
} |
|
|
|
impl<'borrow, T> iter::IntoIterator for &'borrow RepeatedMut<'_, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'borrow, |
|
{ |
|
type Item = View<'borrow, T>; |
|
type IntoIter = RepeatedIter<'borrow, T>; |
|
|
|
fn into_iter(self) -> Self::IntoIter { |
|
RepeatedIter { view: self.as_view(), current_index: 0 } |
|
} |
|
} |
|
|
|
impl<'msg, 'view, T, ViewT> Extend<ViewT> for RepeatedMut<'msg, T> |
|
where |
|
T: ProxiedInRepeated + ?Sized + 'view, |
|
ViewT: Into<View<'view, T>>, |
|
{ |
|
fn extend<I: IntoIterator<Item = ViewT>>(&mut self, iter: I) { |
|
for item in iter { |
|
self.push(item.into()); |
|
} |
|
} |
|
} |
|
|
|
#[cfg(test)] |
|
mod tests { |
|
use super::*; |
|
use googletest::prelude::*; |
|
|
|
#[test] |
|
fn test_primitive_repeated() { |
|
macro_rules! primitive_repeated_tests { |
|
($($t:ty => [$($vals:expr),* $(,)?]),* $(,)?) => { |
|
$({ |
|
// Constructs a new, owned, `Repeated`, only used for tests. |
|
let mut r = Repeated::<$t>::new(); |
|
let mut r = r.as_mut(); |
|
assert_that!(r.len(), eq(0)); |
|
assert!(r.iter().next().is_none(), "starts with empty iter"); |
|
assert!(r.iter().next().is_none(), "starts with empty mut iter"); |
|
assert!(r.is_empty(), "starts is_empty"); |
|
|
|
let mut expected_len = 0usize; |
|
$( |
|
let val: View<$t> = $vals; |
|
r.push(val); |
|
assert_that!(r.get(expected_len), eq(Some(val))); |
|
expected_len += 1; |
|
assert_that!(r.len(), eq(expected_len)); |
|
|
|
)* |
|
assert_that!( |
|
r.iter().collect::<Vec<$t>>(), elements_are![$(eq($vals)),*]); |
|
r.set(0, <$t as Default>::default()); |
|
assert_that!(r.get(0).expect("elem 0"), eq(<$t as Default>::default())); |
|
|
|
r.clear(); |
|
assert!(r.is_empty(), "is_empty after clear"); |
|
assert!(r.iter().next().is_none(), "iter empty after clear"); |
|
assert!(r.into_iter().next().is_none(), "mut iter empty after clear"); |
|
})* |
|
} |
|
} |
|
primitive_repeated_tests!( |
|
u32 => [1,2,3], |
|
i32 => [1,2], |
|
f64 => [10.0, 0.1234f64], |
|
bool => [false, true, true, false], |
|
); |
|
} |
|
|
|
#[test] |
|
fn test_repeated_extend() { |
|
let mut r = Repeated::<i32>::new(); |
|
|
|
r.as_mut().extend([0; 0]); |
|
assert_that!(r.as_mut().len(), eq(0)); |
|
|
|
r.as_mut().extend([0, 1]); |
|
assert_that!(r.as_mut().iter().collect::<Vec<_>>(), elements_are![eq(0), eq(1)]); |
|
let mut x = Repeated::<i32>::new(); |
|
x.as_mut().extend([2, 3]); |
|
|
|
r.as_mut().extend(&x.as_mut()); |
|
|
|
assert_that!( |
|
r.as_mut().iter().collect::<Vec<_>>(), |
|
elements_are![eq(0), eq(1), eq(2), eq(3)] |
|
); |
|
} |
|
}
|
|
|