| use super::*; | |
| /// The raw type-erased version of an owned `Repeated`. | |
| #[derive(Debug)] | |
| #[doc(hidden)] | |
| pub struct InnerRepeated { | |
| raw: RawRepeatedField, | |
| arena: Arena, | |
| } | |
| impl InnerRepeated { | |
| pub fn as_mut(&mut self) -> InnerRepeatedMut<'_> { | |
| InnerRepeatedMut::new(self.raw, &self.arena) | |
| } | |
| pub fn raw(&self) -> RawRepeatedField { | |
| self.raw | |
| } | |
| pub fn arena(&self) -> &Arena { | |
| &self.arena | |
| } | |
| /// # Safety | |
| /// - `raw` must be a valid `RawRepeatedField` | |
| pub unsafe fn from_raw_parts(raw: RawRepeatedField, arena: Arena) -> Self { | |
| Self { raw, arena } | |
| } | |
| } | |
| /// The raw type-erased pointer version of `RepeatedMut`. | |
| #[derive(Clone, Copy, Debug)] | |
| #[doc(hidden)] | |
| pub struct InnerRepeatedMut<'msg> { | |
| pub(crate) raw: RawRepeatedField, | |
| arena: &'msg Arena, | |
| } | |
| impl<'msg> InnerRepeatedMut<'msg> { | |
| #[doc(hidden)] | |
| pub fn new(raw: RawRepeatedField, arena: &'msg Arena) -> Self { | |
| InnerRepeatedMut { raw, arena } | |
| } | |
| } | |
| unsafe impl<T> Singular for T | |
| where | |
| T: EntityType + UpbTypeConversions<T::Tag>, | |
| { | |
| fn repeated_new(_private: Private) -> Repeated<Self> { | |
| let arena = Arena::new(); | |
| Repeated::from_inner(Private, unsafe { | |
| InnerRepeated::from_raw_parts(upb_Array_New(arena.raw(), T::upb_type()), arena) | |
| }) | |
| } | |
| unsafe fn repeated_free(_private: Private, _repeated: &mut Repeated<Self>) { | |
| // No-op: the memory will be dropped by the arena. | |
| } | |
| fn repeated_len(_private: Private, repeated: View<Repeated<Self>>) -> usize { | |
| // SAFETY: `repeated.as_raw()` is a valid `upb_Array*`. | |
| unsafe { upb_Array_Size(repeated.as_raw(Private)) } | |
| } | |
| fn repeated_push( | |
| _private: Private, | |
| mut repeated: Mut<Repeated<Self>>, | |
| val: impl IntoProxied<Self>, | |
| ) { | |
| // SAFETY: | |
| // - `repeated.as_raw()` is a valid `upb_Array*`. | |
| // - `msg_ptr` is a valid `upb_Message*`. | |
| unsafe { | |
| upb_Array_Append( | |
| repeated.as_raw(Private), | |
| T::into_message_value_fuse_if_required( | |
| repeated.raw_arena(Private), | |
| val.into_proxied(Private), | |
| ), | |
| repeated.raw_arena(Private), | |
| ); | |
| }; | |
| } | |
| fn repeated_clear(_private: Private, mut repeated: Mut<Repeated<Self>>) { | |
| // SAFETY: | |
| // - `repeated.as_raw()` is a valid `upb_Array*`. | |
| unsafe { upb_Array_Resize(repeated.as_raw(Private), 0, repeated.raw_arena(Private)) }; | |
| } | |
| fn repeated_truncate(_private: Private, mut repeated: Mut<Repeated<Self>>, new_len: usize) { | |
| // SAFETY: | |
| // - `repeated.as_raw()` is a valid `upb_Array*`. | |
| unsafe { | |
| debug_assert!(new_len <= upb_Array_Size(repeated.as_raw(Private))); | |
| upb_Array_Resize(repeated.as_raw(Private), new_len, repeated.raw_arena(Private)); | |
| } | |
| } | |
| unsafe fn repeated_get_unchecked<'a>( | |
| _private: Private, | |
| repeated: View<'a, Repeated<Self>>, | |
| index: usize, | |
| ) -> View<'a, Self> { | |
| // SAFETY: | |
| // - `repeated.as_raw()` is a valid `const upb_Array*`. | |
| // - `index < len(repeated)` is promised by the caller. | |
| let val = unsafe { upb_Array_Get(repeated.as_raw(Private), index) }; | |
| // SAFETY: | |
| // - `val` has the correct variant for Self. | |
| // - `val` is valid for `'a` lifetime. | |
| unsafe { Self::from_message_value(val) } | |
| } | |
| unsafe fn repeated_get_mut_unchecked<'a>( | |
| _private: Private, | |
| mut repeated: Mut<'a, Repeated<Self>>, | |
| index: usize, | |
| ) -> Mut<'a, Self> | |
| where | |
| Self: Message, | |
| { | |
| // SAFETY: | |
| // - `repeated.as_raw()` is a valid `upb_Array*`. | |
| // - `repeated` is a an array of message-valued elements. | |
| // - `index < len(repeated)` is promised by the caller. | |
| let val = unsafe { upb_Array_GetMutable(repeated.as_raw(Private), index) }; | |
| // SAFETY: | |
| // - `val` is the correct variant for `Self`. | |
| // - `val` is valid for `'a` lifetime. | |
| unsafe { Self::from_message_mut(val, repeated.arena(Private)) } | |
| } | |
| unsafe fn repeated_set_unchecked( | |
| _private: Private, | |
| mut repeated: Mut<Repeated<Self>>, | |
| index: usize, | |
| val: impl IntoProxied<Self>, | |
| ) { | |
| unsafe { | |
| upb_Array_Set( | |
| repeated.as_raw(Private), | |
| index, | |
| T::into_message_value_fuse_if_required( | |
| repeated.raw_arena(Private), | |
| val.into_proxied(Private), | |
| ), | |
| ) | |
| } | |
| } | |
| fn repeated_copy_from( | |
| _private: Private, | |
| src: View<Repeated<Self>>, | |
| mut dest: Mut<Repeated<Self>>, | |
| ) { | |
| // SAFETY: | |
| // - `src.as_raw()` and `dest.as_raw()` are both valid arrays of `Self`. | |
| // - `dest.as_raw()` is mutable. | |
| // - `dest.raw_arena()` will outlive `dest.as_raw()`. | |
| unsafe { | |
| Self::copy_repeated(src.as_raw(Private), dest.as_raw(Private), dest.raw_arena(Private)); | |
| } | |
| } | |
| fn repeated_reserve(_private: Private, mut repeated: Mut<Repeated<Self>>, additional: usize) { | |
| // SAFETY: | |
| // - `repeated.as_raw()` is a valid `upb_Array*`. | |
| unsafe { | |
| let size = upb_Array_Size(repeated.as_raw(Private)); | |
| upb_Array_Reserve( | |
| repeated.as_raw(Private), | |
| size + additional, | |
| repeated.raw_arena(Private), | |
| ); | |
| } | |
| } | |
| } | |
| impl<'msg, T> RepeatedMut<'msg, T> { | |
| // Returns a `RawArena` which is live for at least `'msg` | |
| #[doc(hidden)] | |
| pub fn raw_arena(&mut self, _private: Private) -> RawArena { | |
| self.inner.arena.raw() | |
| } | |
| // Returns an `Arena` which is live for at least `'msg` | |
| #[doc(hidden)] | |
| pub fn arena(&self, _private: Private) -> &'msg Arena { | |
| self.inner.arena | |
| } | |
| } | |
| /// Returns a static empty RepeatedView. | |
| pub fn empty_array<T: Singular>() -> RepeatedView<'static, T> { | |
| // TODO: Consider creating a static empty array in C. | |
| // Use `i32` for a shared empty repeated for all repeated types in the program. | |
| static EMPTY_REPEATED_VIEW: OnceLock<Repeated<i32>> = OnceLock::new(); | |
| // SAFETY: | |
| // - Because the repeated is never mutated, the repeated type is unused and therefore valid for | |
| // `T`. | |
| unsafe { | |
| RepeatedView::from_raw( | |
| Private, | |
| EMPTY_REPEATED_VIEW.get_or_init(Repeated::new).as_view().as_raw(Private), | |
| ) | |
| } | |
| } |