blob: 0db3f64a9691388535dbac2ceefdffed0bd7e035 [file] [log] [blame]
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -07001// Protocol Buffers - Google's data interchange format
2// Copyright 2023 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
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -08008use std::fmt::{self, Debug};
9use std::iter;
Protobuf Team Bot14dd8e92023-12-15 11:05:56 -080010use std::iter::FusedIterator;
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070011/// Repeated scalar fields are implemented around the runtime-specific
12/// `RepeatedField` struct. `RepeatedField` stores an opaque pointer to the
13/// runtime-specific representation of a repeated scalar (`upb_Array*` on upb,
14/// and `RepeatedField<T>*` on cpp).
15use std::marker::PhantomData;
16
17use crate::{
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -070018 AsMut, AsView, IntoMut, IntoProxied, IntoView, Mut, MutProxied, MutProxy, Proxied, Proxy, View,
19 ViewProxy,
Protobuf Team Bot2678e102024-04-12 13:50:28 -070020 __internal::Private,
21 __runtime::{InnerRepeated, InnerRepeatedMut, RawRepeatedField},
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070022};
23
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080024/// Views the elements in a `repeated` field of `T`.
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070025#[repr(transparent)]
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -070026pub struct RepeatedView<'msg, T> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080027 // This does not need to carry an arena in upb, so it can be just the raw repeated field
28 raw: RawRepeatedField,
29 _phantom: PhantomData<&'msg T>,
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070030}
31
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -070032impl<'msg, T> Copy for RepeatedView<'msg, T> {}
33impl<'msg, T> Clone for RepeatedView<'msg, T> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080034 fn clone(&self) -> Self {
35 *self
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070036 }
37}
38
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -070039unsafe impl<'msg, T> Sync for RepeatedView<'msg, T> {}
40unsafe impl<'msg, T> Send for RepeatedView<'msg, T> {}
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070041
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -070042impl<'msg, T> Debug for RepeatedView<'msg, T> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080043 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 f.debug_struct("RepeatedView").field("raw", &self.raw).finish()
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070045 }
46}
47
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080048/// Mutates the elements in a `repeated` field of `T`.
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -070049pub struct RepeatedMut<'msg, T> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080050 pub(crate) inner: InnerRepeatedMut<'msg>,
51 _phantom: PhantomData<&'msg mut T>,
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070052}
53
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -070054unsafe impl<'msg, T> Sync for RepeatedMut<'msg, T> {}
Kevin King65cdac42023-10-23 14:50:42 -070055
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -070056impl<'msg, T> Debug for RepeatedMut<'msg, T> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080057 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Alyssa Haroldsenb6ea6f92024-01-17 16:50:36 -080058 f.debug_struct("RepeatedMut").field("raw", &self.inner.raw).finish()
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070059 }
60}
61
Alyssa Haroldsen3657e052024-02-05 12:51:41 -080062#[doc(hidden)]
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -070063impl<'msg, T> RepeatedView<'msg, T> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080064 #[doc(hidden)]
Derek Benson904266d2024-05-13 07:16:57 -070065 #[inline]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080066 pub fn as_raw(&self, _private: Private) -> RawRepeatedField {
67 self.raw
68 }
69
70 /// # Safety
71 /// - `inner` must be valid to read from for `'msg`
72 #[doc(hidden)]
Derek Benson904266d2024-05-13 07:16:57 -070073 #[inline]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080074 pub unsafe fn from_raw(_private: Private, raw: RawRepeatedField) -> Self {
75 Self { raw, _phantom: PhantomData }
76 }
Alyssa Haroldsen3657e052024-02-05 12:51:41 -080077}
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080078
Alyssa Haroldsen3657e052024-02-05 12:51:41 -080079impl<'msg, T> RepeatedView<'msg, T>
80where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -070081 T: ProxiedInRepeated + 'msg,
Alyssa Haroldsen3657e052024-02-05 12:51:41 -080082{
Alyssa Haroldsenfcf0d012023-12-18 10:13:01 -080083 /// Gets the length of the repeated field.
Derek Benson904266d2024-05-13 07:16:57 -070084 #[inline]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080085 pub fn len(&self) -> usize {
86 T::repeated_len(*self)
87 }
Alyssa Haroldsenfcf0d012023-12-18 10:13:01 -080088
89 /// Returns true if the repeated field has no values.
Derek Benson904266d2024-05-13 07:16:57 -070090 #[inline]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080091 pub fn is_empty(&self) -> bool {
92 self.len() == 0
93 }
Alyssa Haroldsenfcf0d012023-12-18 10:13:01 -080094
95 /// Gets the value at `index`.
96 ///
97 /// Returns `None` if `index > len`.
Derek Benson904266d2024-05-13 07:16:57 -070098 #[inline]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -080099 pub fn get(self, index: usize) -> Option<View<'msg, T>> {
100 if index >= self.len() {
101 return None;
102 }
103 // SAFETY: `index` has been checked to be in-bounds
Alyssa Haroldsenfcf0d012023-12-18 10:13:01 -0800104 Some(unsafe { self.get_unchecked(index) })
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800105 }
Alyssa Haroldsenfcf0d012023-12-18 10:13:01 -0800106
107 /// Gets the value at `index` without bounds-checking.
108 ///
109 /// # Safety
110 /// Undefined behavior if `index >= len`
Derek Benson904266d2024-05-13 07:16:57 -0700111 #[inline]
Alyssa Haroldsenfcf0d012023-12-18 10:13:01 -0800112 pub unsafe fn get_unchecked(self, index: usize) -> View<'msg, T> {
113 // SAFETY: in-bounds as promised
114 unsafe { T::repeated_get_unchecked(self, index) }
115 }
116
117 /// Iterates over the values in the repeated field.
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800118 pub fn iter(self) -> RepeatedIter<'msg, T> {
119 self.into_iter()
120 }
121}
122
Alyssa Haroldsen3657e052024-02-05 12:51:41 -0800123#[doc(hidden)]
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700124impl<'msg, T> RepeatedMut<'msg, T> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800125 /// # Safety
126 /// - `inner` must be valid to read and write from for `'msg`
127 /// - There must be no aliasing references or mutations on the same
128 /// underlying object.
129 #[doc(hidden)]
Derek Benson904266d2024-05-13 07:16:57 -0700130 #[inline]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800131 pub unsafe fn from_inner(_private: Private, inner: InnerRepeatedMut<'msg>) -> Self {
132 Self { inner, _phantom: PhantomData }
133 }
134
135 #[doc(hidden)]
Derek Benson904266d2024-05-13 07:16:57 -0700136 #[inline]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800137 pub fn as_raw(&mut self, _private: Private) -> RawRepeatedField {
138 self.inner.raw
139 }
Alyssa Haroldsen3657e052024-02-05 12:51:41 -0800140}
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800141
Alyssa Haroldsen3657e052024-02-05 12:51:41 -0800142impl<'msg, T> RepeatedMut<'msg, T>
143where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700144 T: ProxiedInRepeated + 'msg,
Alyssa Haroldsen3657e052024-02-05 12:51:41 -0800145{
Alyssa Haroldsenb6ea6f92024-01-17 16:50:36 -0800146 /// Gets the length of the repeated field.
Derek Benson904266d2024-05-13 07:16:57 -0700147 #[inline]
Alyssa Haroldsenb6ea6f92024-01-17 16:50:36 -0800148 pub fn len(&self) -> usize {
149 self.as_view().len()
150 }
151
152 /// Returns true if the repeated field has no values.
Derek Benson904266d2024-05-13 07:16:57 -0700153 #[inline]
Alyssa Haroldsenb6ea6f92024-01-17 16:50:36 -0800154 pub fn is_empty(&self) -> bool {
155 self.len() == 0
156 }
157
158 /// Gets the value at `index`.
159 ///
160 /// Returns `None` if `index > len`.
Derek Benson904266d2024-05-13 07:16:57 -0700161 #[inline]
Alyssa Haroldsenb6ea6f92024-01-17 16:50:36 -0800162 pub fn get(&self, index: usize) -> Option<View<T>> {
163 self.as_view().get(index)
164 }
165
166 /// Gets the value at `index` without bounds-checking.
167 ///
168 /// # Safety
169 /// Undefined behavior if `index >= len`
Derek Benson904266d2024-05-13 07:16:57 -0700170 #[inline]
Alyssa Haroldsenb6ea6f92024-01-17 16:50:36 -0800171 pub unsafe fn get_unchecked(&self, index: usize) -> View<T> {
172 // SAFETY: in-bounds as promised
173 unsafe { self.as_view().get_unchecked(index) }
174 }
175
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800176 /// Appends `val` to the end of the repeated field.
Derek Benson904266d2024-05-13 07:16:57 -0700177 #[inline]
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700178 pub fn push(&mut self, val: impl IntoProxied<T>) {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800179 T::repeated_push(self.as_mut(), val);
180 }
181
182 /// Sets the value at `index` to the value `val`.
183 ///
184 /// # Panics
185 /// Panics if `index >= len`
Derek Benson904266d2024-05-13 07:16:57 -0700186 #[inline]
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700187 pub fn set(&mut self, index: usize, val: impl IntoProxied<T>) {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800188 let len = self.len();
189 if index >= len {
190 panic!("index {index} >= repeated len {len}");
191 }
Alyssa Haroldsenfcf0d012023-12-18 10:13:01 -0800192 unsafe { self.set_unchecked(index, val) }
193 }
194
195 /// Sets the value at `index` to the value `val`.
196 ///
197 /// # Safety
198 /// Undefined behavior if `index >= len`
Derek Benson904266d2024-05-13 07:16:57 -0700199 #[inline]
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700200 pub unsafe fn set_unchecked(&mut self, index: usize, val: impl IntoProxied<T>) {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800201 unsafe { T::repeated_set_unchecked(self.as_mut(), index, val) }
202 }
203
Alyssa Haroldsenb6ea6f92024-01-17 16:50:36 -0800204 /// Iterates over the values in the repeated field.
205 pub fn iter(&self) -> RepeatedIter<T> {
206 self.as_view().into_iter()
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800207 }
208
209 /// Copies from the `src` repeated field into this one.
210 ///
211 /// Also provided by [`MutProxy::set`].
212 pub fn copy_from(&mut self, src: RepeatedView<'_, T>) {
213 T::repeated_copy_from(src, self.as_mut())
214 }
Alyssa Haroldsenf51182b2023-12-14 14:07:40 -0800215
216 /// Clears the repeated field.
217 pub fn clear(&mut self) {
218 T::repeated_clear(self.as_mut())
219 }
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800220}
221
Jakob Buchgraberb6e0a482024-05-06 05:16:05 -0700222impl<T> Repeated<T>
223where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700224 T: ProxiedInRepeated,
Jakob Buchgraberb6e0a482024-05-06 05:16:05 -0700225{
226 pub fn as_view(&self) -> View<Repeated<T>> {
227 RepeatedView { raw: self.inner.raw(), _phantom: PhantomData }
228 }
229
230 #[doc(hidden)]
231 pub fn inner(&self, _private: Private) -> &InnerRepeated {
232 &self.inner
233 }
234}
235
236impl<T> IntoProxied<Repeated<T>> for Repeated<T>
237where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700238 T: ProxiedInRepeated,
Jakob Buchgraberb6e0a482024-05-06 05:16:05 -0700239{
Marcel Hlopkofe696392024-06-12 05:26:09 -0700240 fn into_proxied(self, _private: Private) -> Repeated<T> {
Jakob Buchgraberb6e0a482024-05-06 05:16:05 -0700241 self
242 }
243}
244
245impl<'msg, T> IntoProxied<Repeated<T>> for RepeatedView<'msg, T>
246where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700247 T: 'msg + ProxiedInRepeated,
Jakob Buchgraberb6e0a482024-05-06 05:16:05 -0700248{
Marcel Hlopkofe696392024-06-12 05:26:09 -0700249 fn into_proxied(self, _private: Private) -> Repeated<T> {
Jakob Buchgraberb6e0a482024-05-06 05:16:05 -0700250 let mut repeated: Repeated<T> = Repeated::new();
251 T::repeated_copy_from(self, repeated.as_mut());
252 repeated
253 }
254}
255
256impl<'msg, T> IntoProxied<Repeated<T>> for RepeatedMut<'msg, T>
257where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700258 T: 'msg + ProxiedInRepeated,
Jakob Buchgraberb6e0a482024-05-06 05:16:05 -0700259{
Marcel Hlopkofe696392024-06-12 05:26:09 -0700260 fn into_proxied(self, _private: Private) -> Repeated<T> {
261 IntoProxied::into_proxied(self.as_view(), _private)
Jakob Buchgraberb6e0a482024-05-06 05:16:05 -0700262 }
263}
264
Derek Bensoncee9da92024-07-15 11:59:14 -0700265impl<'msg, T, I, U> IntoProxied<Repeated<T>> for I
266where
267 I: Iterator<Item = U>,
268 T: 'msg + ProxiedInRepeated,
269 U: IntoProxied<T>,
270{
271 fn into_proxied(self, _private: Private) -> Repeated<T> {
272 let mut repeated: Repeated<T> = Repeated::new();
273 repeated.as_mut().extend(self);
274 repeated
275 }
276}
277
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800278/// Types that can appear in a `Repeated<T>`.
279///
280/// This trait is implemented by generated code to communicate how the proxied
281/// type can be manipulated for a repeated field.
282///
283/// Scalars and messages implement `ProxiedInRepeated`.
284///
285/// # Safety
286/// - It must be sound to call `*_unchecked*(x)` with an `index` less than
287/// `repeated_len(x)`.
288pub unsafe trait ProxiedInRepeated: Proxied {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800289 /// Constructs a new owned `Repeated` field.
290 #[doc(hidden)]
Derek Benson9c994242024-07-15 12:36:48 -0700291 fn repeated_new(_private: Private) -> Repeated<Self>;
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800292
Alyssa Haroldsenf51182b2023-12-14 14:07:40 -0800293 /// Frees the repeated field in-place, for use in `Drop`.
294 ///
295 /// # Safety
296 /// - After `repeated_free`, no other methods on the input are safe to call.
297 #[doc(hidden)]
Derek Benson9c994242024-07-15 12:36:48 -0700298 unsafe fn repeated_free(_private: Private, _repeated: &mut Repeated<Self>);
Alyssa Haroldsenf51182b2023-12-14 14:07:40 -0800299
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800300 /// Gets the length of the repeated field.
301 fn repeated_len(repeated: View<Repeated<Self>>) -> usize;
302
303 /// Appends a new element to the end of the repeated field.
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700304 fn repeated_push(repeated: Mut<Repeated<Self>>, val: impl IntoProxied<Self>);
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800305
Alyssa Haroldsenf51182b2023-12-14 14:07:40 -0800306 /// Clears the repeated field of elements.
307 fn repeated_clear(repeated: Mut<Repeated<Self>>);
308
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800309 /// # Safety
310 /// `index` must be less than `Self::repeated_len(repeated)`
311 unsafe fn repeated_get_unchecked(repeated: View<Repeated<Self>>, index: usize) -> View<Self>;
312
313 /// # Safety
314 /// `index` must be less than `Self::repeated_len(repeated)`
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700315 unsafe fn repeated_set_unchecked(
316 repeated: Mut<Repeated<Self>>,
317 index: usize,
318 val: impl IntoProxied<Self>,
319 );
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800320
321 /// Copies the values in the `src` repeated field into `dest`.
322 fn repeated_copy_from(src: View<Repeated<Self>>, dest: Mut<Repeated<Self>>);
Derek Bensonf2d8c2b2024-05-13 05:48:10 -0700323
324 /// Ensures that the repeated field has enough space allocated to insert at
325 /// least `additional` values without an allocation.
326 fn repeated_reserve(repeated: Mut<Repeated<Self>>, additional: usize);
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800327}
328
329/// An iterator over the values inside of a [`View<Repeated<T>>`](RepeatedView).
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700330pub struct RepeatedIter<'msg, T> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800331 view: RepeatedView<'msg, T>,
332 current_index: usize,
333}
334
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700335impl<'msg, T> Debug for RepeatedIter<'msg, T> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800336 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
337 f.debug_struct("RepeatedIter")
338 .field("view", &self.view)
339 .field("current_index", &self.current_index)
340 .finish()
341 }
342}
343
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800344/// A `repeated` field of `T`, used as the owned target for `Proxied`.
345///
346/// Users will generally write [`View<Repeated<T>>`](RepeatedView) or
347/// [`Mut<Repeated<T>>`](RepeatedMut) to access the repeated elements
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700348pub struct Repeated<T: ProxiedInRepeated> {
Jakob Buchgraberb6e0a482024-05-06 05:16:05 -0700349 pub(crate) inner: InnerRepeated,
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800350 _phantom: PhantomData<T>,
351}
352
Jakob Buchgraber3c9978d2024-06-04 01:27:57 -0700353// SAFETY: `Repeated` is Sync because it does not implement interior mutability.
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700354unsafe impl<T: ProxiedInRepeated> Sync for Repeated<T> {}
Jakob Buchgraber3c9978d2024-06-04 01:27:57 -0700355
356// SAFETY: `Repeated` is Send because it's not bound to a specific thread e.g.
357// it does not use thread-local data or similar.
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700358unsafe impl<T: ProxiedInRepeated> Send for Repeated<T> {}
Jakob Buchgraber3c9978d2024-06-04 01:27:57 -0700359
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700360impl<T: ProxiedInRepeated> Repeated<T> {
Jakob Buchgraberad5e55a2024-03-12 05:45:32 -0700361 pub fn new() -> Self {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800362 T::repeated_new(Private)
363 }
364
Derek Benson9c994242024-07-15 12:36:48 -0700365 pub fn from_inner(_private: Private, inner: InnerRepeated) -> Self {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800366 Self { inner, _phantom: PhantomData }
367 }
368
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800369 pub(crate) fn as_mut(&mut self) -> RepeatedMut<'_, T> {
Protobuf Team Bot9ff062c2024-03-12 04:48:15 -0700370 RepeatedMut { inner: self.inner.as_mut(), _phantom: PhantomData }
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800371 }
372}
373
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700374impl<T: ProxiedInRepeated> Default for Repeated<T> {
Jakob Buchgraberad5e55a2024-03-12 05:45:32 -0700375 fn default() -> Self {
376 Repeated::new()
377 }
378}
379
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700380impl<T: ProxiedInRepeated> Drop for Repeated<T> {
Alyssa Haroldsenf51182b2023-12-14 14:07:40 -0800381 fn drop(&mut self) {
382 // SAFETY: only called once
383 unsafe { T::repeated_free(Private, self) }
384 }
385}
386
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800387impl<T> Proxied for Repeated<T>
388where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700389 T: ProxiedInRepeated,
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800390{
391 type View<'msg> = RepeatedView<'msg, T> where Repeated<T>: 'msg;
Jakob Buchgraber1a7ce612024-04-24 06:21:54 -0700392}
393
394impl<T> MutProxied for Repeated<T>
395where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700396 T: ProxiedInRepeated,
Jakob Buchgraber1a7ce612024-04-24 06:21:54 -0700397{
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800398 type Mut<'msg> = RepeatedMut<'msg, T> where Repeated<T>: 'msg;
399}
400
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700401impl<'msg, T> Proxy<'msg> for RepeatedView<'msg, T> where T: ProxiedInRepeated + 'msg {}
402
403impl<'msg, T> AsView for RepeatedView<'msg, T>
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800404where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700405 T: ProxiedInRepeated + 'msg,
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800406{
407 type Proxied = Repeated<T>;
408
Derek Benson904266d2024-05-13 07:16:57 -0700409 #[inline]
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700410 fn as_view(&self) -> View<'msg, Self::Proxied> {
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800411 *self
412 }
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700413}
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800414
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700415impl<'msg, T> IntoView<'msg> for RepeatedView<'msg, T>
416where
417 T: ProxiedInRepeated + 'msg,
418{
Derek Benson904266d2024-05-13 07:16:57 -0700419 #[inline]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800420 fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
421 where
422 'msg: 'shorter,
423 {
424 RepeatedView { raw: self.raw, _phantom: PhantomData }
425 }
426}
427
Protobuf Team Botcf948e42024-07-18 10:01:55 -0700428impl<'msg, T> ViewProxy<'msg> for RepeatedView<'msg, T> where T: ProxiedInRepeated + 'msg {}
429
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700430impl<'msg, T> Proxy<'msg> for RepeatedMut<'msg, T> where T: ProxiedInRepeated + 'msg {}
431
432impl<'msg, T> AsView for RepeatedMut<'msg, T>
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800433where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700434 T: ProxiedInRepeated + 'msg,
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800435{
436 type Proxied = Repeated<T>;
437
Derek Benson904266d2024-05-13 07:16:57 -0700438 #[inline]
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700439 fn as_view(&self) -> RepeatedView<'_, T> {
Alyssa Haroldsenb6ea6f92024-01-17 16:50:36 -0800440 RepeatedView { raw: self.inner.raw, _phantom: PhantomData }
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800441 }
442}
443
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700444impl<'msg, T> IntoView<'msg> for RepeatedMut<'msg, T>
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800445where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700446 T: ProxiedInRepeated + 'msg,
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800447{
Derek Benson904266d2024-05-13 07:16:57 -0700448 #[inline]
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700449 fn into_view<'shorter>(self) -> RepeatedView<'shorter, T>
450 where
451 'msg: 'shorter,
452 {
453 RepeatedView { raw: self.inner.raw, _phantom: PhantomData }
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800454 }
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700455}
456
457impl<'msg, T> AsMut for RepeatedMut<'msg, T>
458where
459 T: ProxiedInRepeated + 'msg,
460{
461 type MutProxied = Repeated<T>;
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800462
Derek Benson904266d2024-05-13 07:16:57 -0700463 #[inline]
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700464 fn as_mut(&mut self) -> RepeatedMut<'_, T> {
465 RepeatedMut { inner: self.inner, _phantom: PhantomData }
466 }
467}
468
469impl<'msg, T> IntoMut<'msg> for RepeatedMut<'msg, T>
470where
471 T: ProxiedInRepeated + 'msg,
472{
473 #[inline]
474 fn into_mut<'shorter>(self) -> RepeatedMut<'shorter, T>
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800475 where
476 'msg: 'shorter,
477 {
478 RepeatedMut { inner: self.inner, _phantom: PhantomData }
479 }
480}
481
Protobuf Team Bot3c95fc82024-07-23 07:54:29 -0700482impl<'msg, T> MutProxy<'msg> for RepeatedMut<'msg, T> where T: ProxiedInRepeated + 'msg {}
483
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800484impl<'msg, T> iter::Iterator for RepeatedIter<'msg, T>
485where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700486 T: ProxiedInRepeated + 'msg,
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800487{
488 type Item = View<'msg, T>;
489
Derek Benson904266d2024-05-13 07:16:57 -0700490 #[inline]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800491 fn next(&mut self) -> Option<Self::Item> {
492 let val = self.view.get(self.current_index);
493 if val.is_some() {
494 self.current_index += 1;
495 }
496 val
497 }
Alyssa Haroldsen39850822024-02-06 11:06:14 -0800498
499 fn size_hint(&self) -> (usize, Option<usize>) {
500 let len = self.len();
501 (len, Some(len))
502 }
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800503}
504
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700505impl<'msg, T: ProxiedInRepeated> ExactSizeIterator for RepeatedIter<'msg, T> {
Protobuf Team Bot14dd8e92023-12-15 11:05:56 -0800506 fn len(&self) -> usize {
Alyssa Haroldsen39850822024-02-06 11:06:14 -0800507 self.view.len() - self.current_index
Protobuf Team Bot14dd8e92023-12-15 11:05:56 -0800508 }
509}
510
Alyssa Haroldsen39850822024-02-06 11:06:14 -0800511// TODO: impl DoubleEndedIterator
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700512impl<'msg, T: ProxiedInRepeated> FusedIterator for RepeatedIter<'msg, T> {}
Protobuf Team Bot14dd8e92023-12-15 11:05:56 -0800513
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800514impl<'msg, T> iter::IntoIterator for RepeatedView<'msg, T>
515where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700516 T: ProxiedInRepeated + 'msg,
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800517{
518 type Item = View<'msg, T>;
519 type IntoIter = RepeatedIter<'msg, T>;
520
521 fn into_iter(self) -> Self::IntoIter {
522 RepeatedIter { view: self, current_index: 0 }
523 }
524}
525
Alyssa Haroldsene16dd472024-01-17 14:02:06 -0800526impl<'msg, T> iter::IntoIterator for &'_ RepeatedView<'msg, T>
527where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700528 T: ProxiedInRepeated + 'msg,
Alyssa Haroldsene16dd472024-01-17 14:02:06 -0800529{
530 type Item = View<'msg, T>;
531 type IntoIter = RepeatedIter<'msg, T>;
532
533 fn into_iter(self) -> Self::IntoIter {
534 RepeatedIter { view: *self, current_index: 0 }
535 }
536}
537
538impl<'borrow, T> iter::IntoIterator for &'borrow RepeatedMut<'_, T>
539where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700540 T: ProxiedInRepeated + 'borrow,
Alyssa Haroldsene16dd472024-01-17 14:02:06 -0800541{
542 type Item = View<'borrow, T>;
543 type IntoIter = RepeatedIter<'borrow, T>;
544
545 fn into_iter(self) -> Self::IntoIter {
546 RepeatedIter { view: self.as_view(), current_index: 0 }
547 }
548}
549
Protobuf Team Bot7f6a0ba2024-03-29 10:26:49 -0700550impl<'msg, 'view, T, ViewT> Extend<ViewT> for RepeatedMut<'msg, T>
551where
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700552 T: ProxiedInRepeated + 'view,
553 ViewT: IntoProxied<T>,
Protobuf Team Bot7f6a0ba2024-03-29 10:26:49 -0700554{
555 fn extend<I: IntoIterator<Item = ViewT>>(&mut self, iter: I) {
Derek Bensonf2d8c2b2024-05-13 05:48:10 -0700556 let iter = iter.into_iter();
557 T::repeated_reserve(self.as_mut(), iter.size_hint().0);
Protobuf Team Bot7f6a0ba2024-03-29 10:26:49 -0700558 for item in iter {
Jakob Buchgraber0d6e9792024-07-09 04:44:21 -0700559 self.push(item);
Protobuf Team Bot7f6a0ba2024-03-29 10:26:49 -0700560 }
561 }
562}
563
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800564#[cfg(test)]
565mod tests {
566 use super::*;
567 use googletest::prelude::*;
568
Dmitri Gribenko0a917b92024-07-22 06:50:36 -0700569 #[googletest::test]
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800570 fn test_primitive_repeated() {
571 macro_rules! primitive_repeated_tests {
572 ($($t:ty => [$($vals:expr),* $(,)?]),* $(,)?) => {
573 $({
574 // Constructs a new, owned, `Repeated`, only used for tests.
575 let mut r = Repeated::<$t>::new();
576 let mut r = r.as_mut();
577 assert_that!(r.len(), eq(0));
578 assert!(r.iter().next().is_none(), "starts with empty iter");
579 assert!(r.iter().next().is_none(), "starts with empty mut iter");
580 assert!(r.is_empty(), "starts is_empty");
581
582 let mut expected_len = 0usize;
583 $(
584 let val: View<$t> = $vals;
585 r.push(val);
586 assert_that!(r.get(expected_len), eq(Some(val)));
587 expected_len += 1;
588 assert_that!(r.len(), eq(expected_len));
589
590 )*
Bastien Jacot-Guillarmod7b3682f2024-05-03 09:50:45 -0700591 assert_that!(r, elements_are![$(eq($vals)),*]);
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800592 r.set(0, <$t as Default>::default());
593 assert_that!(r.get(0).expect("elem 0"), eq(<$t as Default>::default()));
Alyssa Haroldsenf51182b2023-12-14 14:07:40 -0800594
595 r.clear();
596 assert!(r.is_empty(), "is_empty after clear");
597 assert!(r.iter().next().is_none(), "iter empty after clear");
598 assert!(r.into_iter().next().is_none(), "mut iter empty after clear");
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800599 })*
600 }
601 }
602 primitive_repeated_tests!(
603 u32 => [1,2,3],
604 i32 => [1,2],
605 f64 => [10.0, 0.1234f64],
606 bool => [false, true, true, false],
607 );
608 }
Protobuf Team Bot7f6a0ba2024-03-29 10:26:49 -0700609
Dmitri Gribenko0a917b92024-07-22 06:50:36 -0700610 #[googletest::test]
Protobuf Team Bot7f6a0ba2024-03-29 10:26:49 -0700611 fn test_repeated_extend() {
612 let mut r = Repeated::<i32>::new();
Protobuf Team Bot063c1982024-04-02 06:48:42 -0700613
614 r.as_mut().extend([0; 0]);
615 assert_that!(r.as_mut().len(), eq(0));
616
Protobuf Team Bot7f6a0ba2024-03-29 10:26:49 -0700617 r.as_mut().extend([0, 1]);
Bastien Jacot-Guillarmod7b3682f2024-05-03 09:50:45 -0700618 assert_that!(r.as_mut(), elements_are![eq(0), eq(1)]);
Protobuf Team Bot7f6a0ba2024-03-29 10:26:49 -0700619 let mut x = Repeated::<i32>::new();
620 x.as_mut().extend([2, 3]);
621
622 r.as_mut().extend(&x.as_mut());
623
Bastien Jacot-Guillarmod7b3682f2024-05-03 09:50:45 -0700624 assert_that!(r.as_mut(), elements_are![eq(0), eq(1), eq(2), eq(3)]);
Protobuf Team Bot7f6a0ba2024-03-29 10:26:49 -0700625 }
Derek Bensoncee9da92024-07-15 11:59:14 -0700626
Dmitri Gribenko0a917b92024-07-22 06:50:36 -0700627 #[googletest::test]
Derek Bensoncee9da92024-07-15 11:59:14 -0700628 fn test_repeated_iter_into_proxied() {
629 let r: Repeated<i32> = [0, 1, 2, 3].into_iter().into_proxied(Private);
630 assert_that!(r.as_view(), elements_are![eq(0), eq(1), eq(2), eq(3)]);
631 }
Alyssa Haroldsen6ae76fd2023-12-14 11:44:00 -0800632}