Skip to main content

protobuf/
map.rs

1// 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
8use crate::{
9    AsMut, AsView, IntoMut, IntoProxied, IntoView, Message, Mut, MutProxied, Proxied, Singular,
10    View,
11    __internal::runtime::{InnerMap, InnerMapMut, RawMap, RawMapIter},
12    __internal::{Private, SealedInternal},
13};
14use std::marker::PhantomData;
15
16/// A trait implemented by types which are allowed as keys in maps.
17/// This is all types for fields except for repeated, maps, bytes, messages, enums and floating point types.
18#[doc(inline)]
19pub use crate::__internal::runtime::MapKey;
20
21/// A trait implemented by types which are allowed as values in maps, which is all Singular types.
22/// This trait is distinct from `Singular` only because of the generic `K: MapKey`.
23pub trait MapValue: Singular + SealedInternal {
24    #[doc(hidden)]
25    fn map_new<K: MapKey>(_: Private) -> Map<K, Self>;
26
27    /// # Safety
28    /// - After `map_free`, no other methods on the input are safe to call.
29    #[doc(hidden)]
30    unsafe fn map_free<K: MapKey>(_: Private, map: &mut Map<K, Self>);
31
32    #[doc(hidden)]
33    fn map_clear<K: MapKey>(_: Private, map: MapMut<K, Self>);
34
35    #[doc(hidden)]
36    fn map_len<K: MapKey>(_: Private, map: MapView<K, Self>) -> usize;
37
38    #[doc(hidden)]
39    fn map_insert<K: MapKey>(
40        _: Private,
41        map: MapMut<K, Self>,
42        key: View<'_, K>,
43        value: impl IntoProxied<Self>,
44    ) -> bool;
45
46    #[doc(hidden)]
47    fn map_get<'a, K: MapKey>(
48        _: Private,
49        map: MapView<'a, K, Self>,
50        key: View<'_, K>,
51    ) -> Option<View<'a, Self>>;
52
53    #[doc(hidden)]
54    fn map_get_mut<'a, K: MapKey>(
55        _: Private,
56        map: MapMut<'a, K, Self>,
57        key: View<'_, K>,
58    ) -> Option<Mut<'a, Self>>
59    where
60        Self: Message;
61
62    #[doc(hidden)]
63    fn map_remove<K: MapKey>(_: Private, map: MapMut<K, Self>, key: View<'_, K>) -> bool;
64
65    #[doc(hidden)]
66    fn map_iter<K: MapKey>(_: Private, map: MapView<K, Self>) -> MapIter<K, Self>;
67
68    #[doc(hidden)]
69    fn map_iter_next<'a, K: MapKey>(
70        _: Private,
71        iter: &mut MapIter<'a, K, Self>,
72    ) -> Option<(View<'a, K>, View<'a, Self>)>;
73}
74
75pub struct Map<K: MapKey, V: MapValue> {
76    inner: InnerMap,
77    _phantom: PhantomData<(PhantomData<K>, PhantomData<V>)>,
78}
79
80// SAFETY: `Map` is Sync because it does not implement interior mutability.
81unsafe impl<K: MapKey, V: MapValue> Sync for Map<K, V> {}
82
83// SAFETY: `Map` is Send because it's not bound to a specific thread e.g.
84// it does not use thread-local data or similar.
85unsafe impl<K: MapKey, V: MapValue> Send for Map<K, V> {}
86
87impl<K: MapKey, V: MapValue> SealedInternal for Map<K, V> {}
88
89impl<K: MapKey, V: MapValue> Map<K, V> {
90    pub fn new() -> Self {
91        V::map_new(Private)
92    }
93
94    pub fn as_mut(&mut self) -> MapMut<'_, K, V> {
95        MapMut { inner: self.inner.as_mut(), _phantom: PhantomData }
96    }
97
98    pub fn as_view(&self) -> MapView<'_, K, V> {
99        MapView { raw: self.inner.raw, _phantom: PhantomData }
100    }
101
102    #[doc(hidden)]
103    pub fn from_inner(_: Private, inner: InnerMap) -> Self {
104        Self { inner, _phantom: PhantomData }
105    }
106
107    #[doc(hidden)]
108    pub fn as_raw(&self, _: Private) -> RawMap {
109        self.inner.raw
110    }
111}
112
113impl<K: MapKey, V: MapValue> Default for Map<K, V> {
114    fn default() -> Self {
115        Map::new()
116    }
117}
118
119impl<K: MapKey, V: MapValue> Drop for Map<K, V> {
120    fn drop(&mut self) {
121        // SAFETY:
122        // - `drop` is only called once.
123        // - 'map_free` is only called here.
124        unsafe { V::map_free(Private, self) }
125    }
126}
127
128impl<K: MapKey, V: MapValue> Proxied for Map<K, V> {
129    type View<'msg> = MapView<'msg, K, V>;
130}
131
132impl<K: MapKey, V: MapValue> AsView for Map<K, V> {
133    type Proxied = Self;
134
135    fn as_view(&self) -> MapView<'_, K, V> {
136        self.as_view()
137    }
138}
139
140impl<K: MapKey, V: MapValue> MutProxied for Map<K, V> {
141    type Mut<'msg> = MapMut<'msg, K, V>;
142}
143
144impl<K: MapKey, V: MapValue> AsMut for Map<K, V> {
145    type MutProxied = Self;
146
147    fn as_mut(&mut self) -> MapMut<'_, K, V> {
148        self.as_mut()
149    }
150}
151
152impl<'msg, K, KView, V, VView, I> IntoProxied<Map<K, V>> for I
153where
154    I: Iterator<Item = (KView, VView)>,
155    K: MapKey,
156    V: MapValue,
157    KView: Into<View<'msg, K>>,
158    VView: IntoProxied<V>,
159{
160    fn into_proxied(self, _: Private) -> Map<K, V> {
161        let mut m = Map::<K, V>::new();
162        m.as_mut().extend(self);
163        m
164    }
165}
166
167/// A view of a map field.
168///
169/// This is a proxy type that is conceptually similar to a `&Map<K, V>`
170#[repr(transparent)]
171pub struct MapView<'msg, K: ?Sized, V: ?Sized> {
172    raw: RawMap,
173    _phantom: PhantomData<(&'msg K, &'msg V)>,
174}
175
176impl<'msg, K: ?Sized, V: ?Sized> Copy for MapView<'msg, K, V> {}
177impl<'msg, K: ?Sized, V: ?Sized> Clone for MapView<'msg, K, V> {
178    fn clone(&self) -> Self {
179        *self
180    }
181}
182
183unsafe impl<'msg, K: ?Sized, V: ?Sized> Sync for MapView<'msg, K, V> {}
184unsafe impl<'msg, K: ?Sized, V: ?Sized> Send for MapView<'msg, K, V> {}
185
186impl<'msg, K: ?Sized, V: ?Sized> std::fmt::Debug for MapView<'msg, K, V> {
187    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188        f.debug_tuple("MapView")
189            .field(&std::any::type_name::<K>())
190            .field(&std::any::type_name::<V>())
191            .finish()
192    }
193}
194
195impl<'msg, K: MapKey, V: MapValue> SealedInternal for MapView<'msg, K, V> {}
196
197#[doc(hidden)]
198impl<'msg, K: ?Sized, V: ?Sized> MapView<'msg, K, V> {
199    #[doc(hidden)]
200    pub fn as_raw(&self, _: Private) -> RawMap {
201        self.raw
202    }
203
204    /// # Safety
205    /// - `raw` must be valid to read from for `'msg`.
206    #[doc(hidden)]
207    pub unsafe fn from_raw(_: Private, raw: RawMap) -> Self {
208        Self { raw, _phantom: PhantomData }
209    }
210}
211
212impl<'msg, K: MapKey, V: MapValue> MapView<'msg, K, V> {
213    pub fn get<'a>(self, key: impl Into<View<'a, K>>) -> Option<View<'msg, V>>
214    where
215        K: 'a,
216    {
217        V::map_get(Private, self, key.into())
218    }
219
220    pub fn len(self) -> usize {
221        V::map_len(Private, self)
222    }
223
224    pub fn is_empty(self) -> bool {
225        self.len() == 0
226    }
227
228    /// Returns an iterator visiting all key-value pairs in arbitrary order.
229    ///
230    /// The iterator element type is `(View<K>, View<V>)`.
231    /// This is an alias for `<Self as IntoIterator>::into_iter`.
232    pub fn iter(self) -> MapIter<'msg, K, V> {
233        self.into_iter()
234    }
235
236    /// Returns an iterator visiting all keys in arbitrary order.
237    ///
238    /// The iterator element type is `View<K>`.
239    pub fn keys(self) -> impl Iterator<Item = View<'msg, K>> + 'msg {
240        self.into_iter().map(|(k, _)| k)
241    }
242
243    /// Returns an iterator visiting all values in arbitrary order.
244    ///
245    /// The iterator element type is `View<V>`.
246    pub fn values(self) -> impl Iterator<Item = View<'msg, V>> + 'msg {
247        self.into_iter().map(|(_, v)| v)
248    }
249}
250
251impl<'msg, K: MapKey, V: MapValue> AsView for MapView<'msg, K, V> {
252    type Proxied = Map<K, V>;
253
254    fn as_view(&self) -> MapView<'_, K, V> {
255        *self
256    }
257}
258
259impl<'msg, K: MapKey, V: MapValue> IntoView<'msg> for MapView<'msg, K, V> {
260    fn into_view<'shorter>(self) -> MapView<'shorter, K, V>
261    where
262        'msg: 'shorter,
263    {
264        MapView { raw: self.raw, _phantom: PhantomData }
265    }
266}
267
268impl<'msg, K: MapKey, V: MapValue> IntoProxied<Map<K, V>> for MapView<'msg, K, V>
269where
270    View<'msg, V>: IntoProxied<V>,
271{
272    fn into_proxied(self, _: Private) -> Map<K, V> {
273        let mut m = Map::<K, V>::new();
274        m.as_mut().copy_from(self);
275        m
276    }
277}
278
279/// A mutable proxy of a map field.
280///
281/// This is a proxy type that is conceptually similar to a `&mut Map<K, V>`
282pub struct MapMut<'msg, K: ?Sized, V: ?Sized> {
283    pub(crate) inner: InnerMapMut<'msg>,
284    _phantom: PhantomData<(&'msg mut K, &'msg mut V)>,
285}
286
287impl<'msg, K: ?Sized, V: ?Sized> MapMut<'msg, K, V> {
288    #[doc(hidden)]
289    pub fn inner(&self, _: Private) -> InnerMapMut<'_> {
290        self.inner
291    }
292}
293
294unsafe impl<'msg, K: ?Sized, V: ?Sized> Sync for MapMut<'msg, K, V> {}
295
296impl<'msg, K: ?Sized, V: ?Sized> std::fmt::Debug for MapMut<'msg, K, V> {
297    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
298        f.debug_tuple("MapMut")
299            .field(&std::any::type_name::<K>())
300            .field(&std::any::type_name::<V>())
301            .finish()
302    }
303}
304
305impl<'msg, K: MapKey, V: MapValue> SealedInternal for MapMut<'msg, K, V> {}
306
307impl<'msg, K: MapKey, V: MapValue> AsView for MapMut<'msg, K, V> {
308    type Proxied = Map<K, V>;
309
310    fn as_view(&self) -> MapView<'_, K, V> {
311        MapView { raw: self.inner.raw, _phantom: PhantomData }
312    }
313}
314
315impl<'msg, K: MapKey, V: MapValue> IntoView<'msg> for MapMut<'msg, K, V> {
316    fn into_view<'shorter>(self) -> MapView<'shorter, K, V>
317    where
318        'msg: 'shorter,
319    {
320        MapView { raw: self.inner.raw, _phantom: PhantomData }
321    }
322}
323
324impl<'msg, K: MapKey, V: MapValue> AsMut for MapMut<'msg, K, V> {
325    type MutProxied = Map<K, V>;
326
327    fn as_mut(&mut self) -> MapMut<'_, K, V> {
328        MapMut { inner: self.inner, _phantom: PhantomData }
329    }
330}
331
332impl<'msg, K: MapKey, V: MapValue> IntoMut<'msg> for MapMut<'msg, K, V> {
333    fn into_mut<'shorter>(self) -> MapMut<'shorter, K, V>
334    where
335        'msg: 'shorter,
336    {
337        MapMut { inner: self.inner, _phantom: PhantomData }
338    }
339}
340
341#[doc(hidden)]
342impl<'msg, K: ?Sized, V: ?Sized> MapMut<'msg, K, V> {
343    /// # Safety
344    /// - `inner` must be valid to read and write from for `'msg`.
345    #[doc(hidden)]
346    pub unsafe fn from_inner(_: Private, inner: InnerMapMut<'msg>) -> Self {
347        Self { inner, _phantom: PhantomData }
348    }
349
350    #[doc(hidden)]
351    pub fn as_raw(&mut self, _: Private) -> RawMap {
352        self.inner.raw
353    }
354}
355
356impl<'msg, K: MapKey, V: MapValue> MapMut<'msg, K, V> {
357    pub fn len(&self) -> usize {
358        self.as_view().len()
359    }
360
361    pub fn is_empty(&self) -> bool {
362        self.len() == 0
363    }
364
365    /// Adds a key-value pair to the map.
366    ///
367    /// Returns `true` if the entry was newly inserted.
368    pub fn insert<'a>(&mut self, key: impl Into<View<'a, K>>, value: impl IntoProxied<V>) -> bool {
369        V::map_insert(Private, self.as_mut(), key.into(), value)
370    }
371
372    pub fn remove<'a>(&mut self, key: impl Into<View<'a, K>>) -> bool {
373        V::map_remove(Private, self.as_mut(), key.into())
374    }
375
376    pub fn clear(&mut self) {
377        V::map_clear(Private, self.as_mut())
378    }
379
380    pub fn get<'a>(&self, key: impl Into<View<'a, K>>) -> Option<View<'_, V>> {
381        V::map_get(Private, self.as_view(), key.into())
382    }
383
384    pub fn get_mut<'a>(&mut self, key: impl Into<View<'a, K>>) -> Option<Mut<'_, V>>
385    where
386        V: Message,
387    {
388        V::map_get_mut(Private, self.as_mut(), key.into())
389    }
390
391    pub fn copy_from<'a>(
392        &mut self,
393        src: impl IntoIterator<Item = (impl Into<View<'a, K>>, impl IntoProxied<V>)>,
394    ) {
395        //TODO
396        self.clear();
397        for (k, v) in src.into_iter() {
398            self.insert(k, v);
399        }
400    }
401
402    /// Returns an iterator visiting all key-value pairs in arbitrary order.
403    ///
404    /// The iterator element type is `(View<K>, View<V>)`.
405    pub fn iter(&self) -> MapIter<'_, K, V> {
406        self.into_iter()
407    }
408
409    /// Returns an iterator visiting all keys in arbitrary order.
410    ///
411    /// The iterator element type is `View<K>`.
412    pub fn keys(&self) -> impl Iterator<Item = View<'_, K>> + '_ {
413        self.as_view().keys()
414    }
415
416    /// Returns an iterator visiting all values in arbitrary order.
417    ///
418    /// The iterator element type is `View<V>`.
419    pub fn values(&self) -> impl Iterator<Item = View<'_, V>> + '_ {
420        self.as_view().values()
421    }
422}
423
424impl<'msg, K: MapKey, V: MapValue> IntoProxied<Map<K, V>> for MapMut<'msg, K, V>
425where
426    View<'msg, V>: IntoProxied<V>,
427{
428    fn into_proxied(self, _: Private) -> Map<K, V> {
429        self.into_view().into_proxied(Private)
430    }
431}
432
433impl<'msg, 'k, KView, VView, K, V> Extend<(KView, VView)> for MapMut<'msg, K, V>
434where
435    K: MapKey,
436    V: MapValue,
437    KView: Into<View<'k, K>>,
438    VView: IntoProxied<V>,
439{
440    fn extend<T: IntoIterator<Item = (KView, VView)>>(&mut self, iter: T) {
441        for (k, v) in iter.into_iter() {
442            self.insert(k, v);
443        }
444    }
445}
446
447/// An iterator visiting all key-value pairs in arbitrary order.
448///
449/// The iterator element type is `(View<Key>, View<Value>)`.
450pub struct MapIter<'msg, K: ?Sized, V: ?Sized> {
451    raw: RawMapIter,
452    _phantom: PhantomData<(&'msg K, &'msg V)>,
453}
454
455impl<'msg, K: ?Sized, V: ?Sized> MapIter<'msg, K, V> {
456    /// # Safety
457    /// - `raw` must be a valid instance of the raw iterator for `'msg`.
458    /// - The untyped `raw` iterator must be for a map of `K,V`.
459    /// - The backing map must be live and unmodified for `'msg`.
460    #[doc(hidden)]
461    pub unsafe fn from_raw(_: Private, raw: RawMapIter) -> Self {
462        Self { raw, _phantom: PhantomData }
463    }
464
465    #[doc(hidden)]
466    pub fn as_raw_mut(&mut self, _: Private) -> &mut RawMapIter {
467        &mut self.raw
468    }
469}
470
471impl<'msg, K: MapKey, V: MapValue> Iterator for MapIter<'msg, K, V> {
472    type Item = (View<'msg, K>, View<'msg, V>);
473
474    fn next(&mut self) -> Option<Self::Item> {
475        V::map_iter_next(Private, self)
476    }
477}
478
479impl<'msg, K: MapKey, V: MapValue> IntoIterator for MapView<'msg, K, V> {
480    type IntoIter = MapIter<'msg, K, V>;
481    type Item = (View<'msg, K>, View<'msg, V>);
482
483    fn into_iter(self) -> MapIter<'msg, K, V> {
484        V::map_iter(Private, self)
485    }
486}
487
488impl<'msg, K: MapKey, V: MapValue> IntoIterator for &'msg Map<K, V> {
489    type IntoIter = MapIter<'msg, K, V>;
490    type Item = (View<'msg, K>, View<'msg, V>);
491
492    fn into_iter(self) -> MapIter<'msg, K, V> {
493        self.as_view().into_iter()
494    }
495}
496
497impl<'a, 'msg, K: MapKey, V: MapValue> IntoIterator for &'a MapView<'msg, K, V>
498where
499    'msg: 'a,
500{
501    type IntoIter = MapIter<'msg, K, V>;
502    type Item = (View<'msg, K>, View<'msg, V>);
503
504    fn into_iter(self) -> MapIter<'msg, K, V> {
505        (*self).into_iter()
506    }
507}
508
509impl<'a, 'msg, K: MapKey, V: MapValue> IntoIterator for &'a MapMut<'msg, K, V>
510where
511    'msg: 'a,
512{
513    type IntoIter = MapIter<'a, K, V>;
514    // The View's are valid for 'a instead of 'msg.
515    // This is because the mutator may mutate past 'a but before 'msg expires.
516    type Item = (View<'a, K>, View<'a, V>);
517
518    fn into_iter(self) -> MapIter<'a, K, V> {
519        self.as_view().into_iter()
520    }
521}
522
523#[cfg(test)]
524mod tests {
525    use super::*;
526    use crate::{ProtoBytes, ProtoStr, ProtoString};
527    use googletest::prelude::*;
528
529    #[gtest]
530    fn test_proxied_scalar() {
531        let mut map: Map<i32, i64> = Map::new();
532        let mut map_mut = map.as_mut();
533        map_mut.insert(1, 2);
534        assert_that!(map_mut.get(1), eq(Some(2)));
535
536        let map_view_1 = map_mut.as_view();
537        assert_that!(map_view_1.len(), eq(1));
538        assert_that!(map_view_1.get(1), eq(Some(2)));
539
540        map_mut.insert(3, 4);
541
542        let map_view_2 = map_mut.into_view();
543        assert_that!(map_view_2.len(), eq(2));
544        assert_that!(map_view_2.get(3), eq(Some(4)));
545
546        {
547            let map_view_3 = map_view_2.as_view();
548            assert_that!(map_view_3.is_empty(), eq(false));
549        }
550
551        let map_view_4 = map_view_2.into_view();
552        assert_that!(map_view_4.is_empty(), eq(false));
553    }
554
555    #[gtest]
556    fn test_proxied_str() {
557        let mut map: Map<ProtoString, ProtoString> = Map::new();
558        let mut map_mut = map.as_mut();
559        map_mut.insert("a", "b");
560
561        let map_view_1 = map_mut.as_view();
562        assert_that!(map_view_1.len(), eq(1));
563        assert_that!(map_view_1.get("a").unwrap(), eq("b"));
564
565        map_mut.insert("c", "d");
566
567        let map_view_2 = map_mut.into_view();
568        assert_that!(map_view_2.len(), eq(2));
569        assert_that!(map_view_2.get("c").unwrap(), eq("d"));
570
571        {
572            let map_view_3 = map_view_2.as_view();
573            assert_that!(map_view_3.is_empty(), eq(false));
574        }
575
576        let map_view_4 = map_view_2.into_view();
577        assert_that!(map_view_4.is_empty(), eq(false));
578    }
579
580    #[gtest]
581    fn test_proxied_iter() {
582        let mut map: Map<i32, ProtoString> = Map::new();
583        let mut map_mut = map.as_mut();
584        map_mut.insert(15, "fizzbuzz");
585        map_mut.insert(5, "buzz");
586        map_mut.insert(3, "fizz");
587
588        // ProtoStr::from_str is necessary below because
589        // https://doc.rust-lang.org/std/primitive.tuple.html#impl-PartialEq-for-(T,)
590        // only compares where the types are the same, even when the tuple types can
591        // compare with each other.
592        // googletest-rust matchers also do not currently implement Clone.
593        assert_that!(
594            map.as_view().iter().collect::<Vec<_>>(),
595            unordered_elements_are![
596                eq(&(3, ProtoStr::from_str("fizz"))),
597                eq(&(5, ProtoStr::from_str("buzz"))),
598                eq(&(15, ProtoStr::from_str("fizzbuzz")))
599            ]
600        );
601        assert_that!(
602            map.as_view(),
603            unordered_elements_are![
604                eq((3, ProtoStr::from_str("fizz"))),
605                eq((5, ProtoStr::from_str("buzz"))),
606                eq((15, ProtoStr::from_str("fizzbuzz")))
607            ]
608        );
609        assert_that!(
610            map.as_mut().iter().collect::<Vec<_>>(),
611            unordered_elements_are![
612                eq(&(3, ProtoStr::from_str("fizz"))),
613                eq(&(5, ProtoStr::from_str("buzz"))),
614                eq(&(15, ProtoStr::from_str("fizzbuzz")))
615            ]
616        );
617        assert_that!(
618            map.as_mut(),
619            unordered_elements_are![
620                eq((3, ProtoStr::from_str("fizz"))),
621                eq((5, ProtoStr::from_str("buzz"))),
622                eq((15, ProtoStr::from_str("fizzbuzz")))
623            ]
624        );
625    }
626
627    #[gtest]
628    fn test_overwrite_insert() {
629        let mut map: Map<i32, ProtoString> = Map::new();
630        let mut map_mut = map.as_mut();
631        assert!(map_mut.insert(0, "fizz"));
632        // insert should return false when the key is already present
633        assert!(!map_mut.insert(0, "buzz"));
634        assert_that!(map.as_mut(), unordered_elements_are![eq((0, ProtoStr::from_str("buzz"))),]);
635    }
636
637    #[gtest]
638    fn test_extend() {
639        let mut map: Map<i32, ProtoString> = Map::new();
640        let mut map_mut = map.as_mut();
641
642        map_mut.extend([(0, ""); 0]);
643        assert_that!(map_mut.len(), eq(0));
644
645        map_mut.extend([(0, "fizz"), (1, "buzz"), (2, "fizzbuzz")]);
646
647        assert_that!(
648            map.as_view(),
649            unordered_elements_are![
650                eq((0, ProtoStr::from_str("fizz"))),
651                eq((1, ProtoStr::from_str("buzz"))),
652                eq((2, ProtoStr::from_str("fizzbuzz")))
653            ]
654        );
655
656        let mut map_2: Map<i32, ProtoString> = Map::new();
657        let mut map_2_mut = map_2.as_mut();
658        map_2_mut.extend([(2, "bing"), (3, "bong")]);
659
660        let mut map_mut = map.as_mut();
661        map_mut.extend(&map_2);
662
663        assert_that!(
664            map.as_view(),
665            unordered_elements_are![
666                eq((0, ProtoStr::from_str("fizz"))),
667                eq((1, ProtoStr::from_str("buzz"))),
668                eq((2, ProtoStr::from_str("bing"))),
669                eq((3, ProtoStr::from_str("bong")))
670            ]
671        );
672    }
673
674    #[gtest]
675    fn test_copy_from() {
676        let mut map: Map<i32, ProtoString> = Map::new();
677        let mut map_mut = map.as_mut();
678        map_mut.copy_from([(0, "fizz"), (1, "buzz"), (2, "fizzbuzz")]);
679
680        assert_that!(
681            map.as_view(),
682            unordered_elements_are![
683                eq((0, ProtoStr::from_str("fizz"))),
684                eq((1, ProtoStr::from_str("buzz"))),
685                eq((2, ProtoStr::from_str("fizzbuzz")))
686            ]
687        );
688
689        let mut map_2: Map<i32, ProtoString> = Map::new();
690        let mut map_2_mut = map_2.as_mut();
691        map_2_mut.copy_from([(2, "bing"), (3, "bong")]);
692
693        let mut map_mut = map.as_mut();
694        map_mut.copy_from(&map_2);
695
696        assert_that!(
697            map.as_view(),
698            unordered_elements_are![
699                eq((2, ProtoStr::from_str("bing"))),
700                eq((3, ProtoStr::from_str("bong")))
701            ]
702        );
703    }
704
705    #[gtest]
706    fn test_all_maps_can_be_constructed() {
707        macro_rules! gen_proto_values {
708            ($key_t:ty, $($value_t:ty),*) => {
709                $(
710                    let map = Map::<$key_t, $value_t>::new();
711                    assert_that!(map.as_view().len(), eq(0));
712                )*
713            }
714        }
715
716        macro_rules! gen_proto_keys {
717            ($($key_t:ty),*) => {
718                $(
719                    gen_proto_values!($key_t, f32, f64, i32, u32, i64, bool, ProtoString, ProtoBytes);
720                )*
721            }
722        }
723
724        gen_proto_keys!(i32, u32, i64, u64, bool, ProtoString);
725    }
726
727    #[gtest]
728    fn test_dbg() {
729        let mut map = Map::<i32, f64>::new();
730        assert_that!(format!("{:?}", map.as_view()), eq("MapView(\"i32\", \"f64\")"));
731        assert_that!(format!("{:?}", map.as_mut()), eq("MapMut(\"i32\", \"f64\")"));
732    }
733}