Skip to main content

tonic/metadata/
map.rs

1/*
2 *
3 * Copyright 2025 gRPC authors.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25use http::HeaderName;
26
27pub(crate) use self::as_encoding_agnostic_metadata_key::AsEncodingAgnosticMetadataKey;
28pub(crate) use self::as_metadata_key::AsMetadataKey;
29pub(crate) use self::into_metadata_key::IntoMetadataKey;
30
31use super::encoding::{Ascii, Binary, ValueEncoding};
32use super::key::{InvalidMetadataKey, MetadataKey};
33use super::value::MetadataValue;
34
35use std::marker::PhantomData;
36
37/// A set of gRPC custom metadata entries.
38///
39/// # Examples
40///
41/// Basic usage
42///
43/// ```
44/// # use tonic::metadata::*;
45/// let mut map = MetadataMap::new();
46///
47/// map.insert("x-host", "example.com".parse().unwrap());
48/// map.insert("x-number", "123".parse().unwrap());
49/// map.insert_bin("trace-proto-bin", MetadataValue::from_bytes(b"[binary data]"));
50///
51/// assert!(map.contains_key("x-host"));
52/// assert!(!map.contains_key("x-location"));
53///
54/// assert_eq!(map.get("x-host").unwrap(), "example.com");
55///
56/// map.remove("x-host");
57///
58/// assert!(!map.contains_key("x-host"));
59/// ```
60#[derive(Clone, Debug, Default)]
61pub struct MetadataMap {
62    headers: http::HeaderMap,
63}
64
65impl AsRef<http::HeaderMap> for MetadataMap {
66    fn as_ref(&self) -> &http::HeaderMap {
67        &self.headers
68    }
69}
70
71impl AsMut<http::HeaderMap> for MetadataMap {
72    fn as_mut(&mut self) -> &mut http::HeaderMap {
73        &mut self.headers
74    }
75}
76
77/// `MetadataMap` entry iterator.
78///
79/// Yields `KeyAndValueRef` values. The same header name may be yielded
80/// more than once if it has more than one associated value.
81#[derive(Debug)]
82pub struct Iter<'a> {
83    inner: http::header::Iter<'a, http::header::HeaderValue>,
84}
85
86/// Reference to a key and an associated value in a `MetadataMap`. It can point
87/// to either an ascii or a binary ("*-bin") key.
88#[derive(Debug)]
89pub enum KeyAndValueRef<'a> {
90    /// An ascii metadata key and value.
91    Ascii(&'a MetadataKey<Ascii>, &'a MetadataValue<Ascii>),
92    /// A binary metadata key and value.
93    Binary(&'a MetadataKey<Binary>, &'a MetadataValue<Binary>),
94}
95
96/// Reference to a key and an associated value in a `MetadataMap`. It can point
97/// to either an ascii or a binary ("*-bin") key.
98#[derive(Debug)]
99pub enum KeyAndMutValueRef<'a> {
100    /// An ascii metadata key and value.
101    Ascii(&'a MetadataKey<Ascii>, &'a mut MetadataValue<Ascii>),
102    /// A binary metadata key and value.
103    Binary(&'a MetadataKey<Binary>, &'a mut MetadataValue<Binary>),
104}
105
106/// `MetadataMap` entry iterator.
107///
108/// Yields `(&MetadataKey, &mut value)` tuples. The same header name may be yielded
109/// more than once if it has more than one associated value.
110#[derive(Debug)]
111pub struct IterMut<'a> {
112    inner: http::header::IterMut<'a, http::header::HeaderValue>,
113}
114
115/// A drain iterator of all values associated with a single metadata key.
116#[derive(Debug)]
117pub struct ValueDrain<'a, VE: ValueEncoding> {
118    inner: http::header::ValueDrain<'a, http::header::HeaderValue>,
119    phantom: PhantomData<VE>,
120}
121
122/// An iterator over `MetadataMap` keys.
123///
124/// Yields `KeyRef` values. Each header name is yielded only once, even if it
125/// has more than one associated value.
126#[derive(Debug)]
127pub struct Keys<'a> {
128    inner: http::header::Keys<'a, http::header::HeaderValue>,
129}
130
131/// Reference to a key in a `MetadataMap`. It can point
132/// to either an ascii or a binary ("*-bin") key.
133#[derive(Debug)]
134pub enum KeyRef<'a> {
135    /// An ascii metadata key and value.
136    Ascii(&'a MetadataKey<Ascii>),
137    /// A binary metadata key and value.
138    Binary(&'a MetadataKey<Binary>),
139}
140
141/// `MetadataMap` value iterator.
142///
143/// Yields `ValueRef` values. Each value contained in the `MetadataMap` will be
144/// yielded.
145#[derive(Debug)]
146pub struct Values<'a> {
147    // Need to use http::header::Iter and not http::header::Values to be able
148    // to know if a value is binary or not.
149    inner: http::header::Iter<'a, http::header::HeaderValue>,
150}
151
152/// Reference to a value in a `MetadataMap`. It can point
153/// to either an ascii or a binary ("*-bin" key) value.
154#[derive(Debug)]
155pub enum ValueRef<'a> {
156    /// An ascii metadata key and value.
157    Ascii(&'a MetadataValue<Ascii>),
158    /// A binary metadata key and value.
159    Binary(&'a MetadataValue<Binary>),
160}
161
162/// `MetadataMap` value iterator.
163///
164/// Each value contained in the `MetadataMap` will be yielded.
165#[derive(Debug)]
166pub struct ValuesMut<'a> {
167    // Need to use http::header::IterMut and not http::header::ValuesMut to be
168    // able to know if a value is binary or not.
169    inner: http::header::IterMut<'a, http::header::HeaderValue>,
170}
171
172/// Reference to a value in a `MetadataMap`. It can point
173/// to either an ascii or a binary ("*-bin" key) value.
174#[derive(Debug)]
175pub enum ValueRefMut<'a> {
176    /// An ascii metadata key and value.
177    Ascii(&'a mut MetadataValue<Ascii>),
178    /// A binary metadata key and value.
179    Binary(&'a mut MetadataValue<Binary>),
180}
181
182/// An iterator of all values associated with a single metadata key.
183#[derive(Debug)]
184pub struct ValueIter<'a, VE: ValueEncoding> {
185    inner: Option<http::header::ValueIter<'a, http::header::HeaderValue>>,
186    phantom: PhantomData<VE>,
187}
188
189/// An iterator of all values associated with a single metadata key.
190#[derive(Debug)]
191pub struct ValueIterMut<'a, VE: ValueEncoding> {
192    inner: http::header::ValueIterMut<'a, http::header::HeaderValue>,
193    phantom: PhantomData<VE>,
194}
195
196/// A view to all values stored in a single entry.
197///
198/// This struct is returned by `MetadataMap::get_all` and
199/// `MetadataMap::get_all_bin`.
200#[derive(Debug)]
201pub struct GetAll<'a, VE: ValueEncoding> {
202    inner: Option<http::header::GetAll<'a, http::header::HeaderValue>>,
203    phantom: PhantomData<VE>,
204}
205
206/// A view into a single location in a `MetadataMap`, which may be vacant or
207/// occupied.
208#[derive(Debug)]
209pub enum Entry<'a, VE: ValueEncoding> {
210    /// An occupied entry
211    Occupied(OccupiedEntry<'a, VE>),
212
213    /// A vacant entry
214    Vacant(VacantEntry<'a, VE>),
215}
216
217/// A view into a single empty location in a `MetadataMap`.
218///
219/// This struct is returned as part of the `Entry` enum.
220#[derive(Debug)]
221pub struct VacantEntry<'a, VE: ValueEncoding> {
222    inner: http::header::VacantEntry<'a, http::header::HeaderValue>,
223    phantom: PhantomData<VE>,
224}
225
226/// A view into a single occupied location in a `MetadataMap`.
227///
228/// This struct is returned as part of the `Entry` enum.
229#[derive(Debug)]
230pub struct OccupiedEntry<'a, VE: ValueEncoding> {
231    inner: http::header::OccupiedEntry<'a, http::header::HeaderValue>,
232    phantom: PhantomData<VE>,
233}
234
235pub(crate) const GRPC_TIMEOUT_HEADER: &str = "grpc-timeout";
236
237// ===== impl MetadataMap =====
238
239impl MetadataMap {
240    // Headers reserved by the gRPC protocol.
241    pub(crate) const GRPC_RESERVED_HEADERS: [HeaderName; 5] = [
242        HeaderName::from_static("te"),
243        HeaderName::from_static("content-type"),
244        HeaderName::from_static("grpc-message"),
245        HeaderName::from_static("grpc-message-type"),
246        HeaderName::from_static("grpc-status"),
247    ];
248
249    /// Create an empty `MetadataMap`.
250    ///
251    /// The map will be created without any capacity. This function will not
252    /// allocate.
253    ///
254    /// # Examples
255    ///
256    /// ```
257    /// # use tonic::metadata::*;
258    /// let map = MetadataMap::new();
259    ///
260    /// assert!(map.is_empty());
261    /// assert_eq!(0, map.capacity());
262    /// ```
263    pub fn new() -> Self {
264        MetadataMap::with_capacity(0)
265    }
266
267    /// Convert an HTTP HeaderMap to a MetadataMap
268    pub fn from_headers(headers: http::HeaderMap) -> Self {
269        MetadataMap { headers }
270    }
271
272    /// Convert a MetadataMap into a HTTP HeaderMap
273    ///
274    /// # Examples
275    ///
276    /// ```
277    /// # use tonic::metadata::*;
278    /// let mut map = MetadataMap::new();
279    /// map.insert("x-host", "example.com".parse().unwrap());
280    ///
281    /// let http_map = map.into_headers();
282    ///
283    /// assert_eq!(http_map.get("x-host").unwrap(), "example.com");
284    /// ```
285    pub fn into_headers(self) -> http::HeaderMap {
286        self.headers
287    }
288
289    pub(crate) fn into_sanitized_headers(mut self) -> http::HeaderMap {
290        for r in &Self::GRPC_RESERVED_HEADERS {
291            self.headers.remove(r);
292        }
293        self.headers
294    }
295
296    /// Create an empty `MetadataMap` with the specified capacity.
297    ///
298    /// The returned map will allocate internal storage in order to hold about
299    /// `capacity` elements without reallocating. However, this is a "best
300    /// effort" as there are usage patterns that could cause additional
301    /// allocations before `capacity` metadata entries are stored in the map.
302    ///
303    /// More capacity than requested may be allocated.
304    ///
305    /// # Examples
306    ///
307    /// ```
308    /// # use tonic::metadata::*;
309    /// let map: MetadataMap = MetadataMap::with_capacity(10);
310    ///
311    /// assert!(map.is_empty());
312    /// assert!(map.capacity() >= 10);
313    /// ```
314    pub fn with_capacity(capacity: usize) -> MetadataMap {
315        MetadataMap {
316            headers: http::HeaderMap::with_capacity(capacity),
317        }
318    }
319
320    /// Returns the number of metadata entries (ascii and binary) stored in the
321    /// map.
322    ///
323    /// This number represents the total number of **values** stored in the map.
324    /// This number can be greater than or equal to the number of **keys**
325    /// stored given that a single key may have more than one associated value.
326    ///
327    /// # Examples
328    ///
329    /// ```
330    /// # use tonic::metadata::*;
331    /// let mut map = MetadataMap::new();
332    ///
333    /// assert_eq!(0, map.len());
334    ///
335    /// map.insert("x-host-ip", "127.0.0.1".parse().unwrap());
336    /// map.insert_bin("x-host-name-bin", MetadataValue::from_bytes(b"localhost"));
337    ///
338    /// assert_eq!(2, map.len());
339    ///
340    /// map.append("x-host-ip", "text/html".parse().unwrap());
341    ///
342    /// assert_eq!(3, map.len());
343    /// ```
344    pub fn len(&self) -> usize {
345        self.headers.len()
346    }
347
348    /// Returns the number of keys (ascii and binary) stored in the map.
349    ///
350    /// This number will be less than or equal to `len()` as each key may have
351    /// more than one associated value.
352    ///
353    /// # Examples
354    ///
355    /// ```
356    /// # use tonic::metadata::*;
357    /// let mut map = MetadataMap::new();
358    ///
359    /// assert_eq!(0, map.keys_len());
360    ///
361    /// map.insert("x-host-ip", "127.0.0.1".parse().unwrap());
362    /// map.insert_bin("x-host-name-bin", MetadataValue::from_bytes(b"localhost"));
363    ///
364    /// assert_eq!(2, map.keys_len());
365    ///
366    /// map.append("x-host-ip", "text/html".parse().unwrap());
367    ///
368    /// assert_eq!(2, map.keys_len());
369    /// ```
370    pub fn keys_len(&self) -> usize {
371        self.headers.keys_len()
372    }
373
374    /// Returns true if the map contains no elements.
375    ///
376    /// # Examples
377    ///
378    /// ```
379    /// # use tonic::metadata::*;
380    /// let mut map = MetadataMap::new();
381    ///
382    /// assert!(map.is_empty());
383    ///
384    /// map.insert("x-host", "hello.world".parse().unwrap());
385    ///
386    /// assert!(!map.is_empty());
387    /// ```
388    pub fn is_empty(&self) -> bool {
389        self.headers.is_empty()
390    }
391
392    /// Clears the map, removing all key-value pairs. Keeps the allocated memory
393    /// for reuse.
394    ///
395    /// # Examples
396    ///
397    /// ```
398    /// # use tonic::metadata::*;
399    /// let mut map = MetadataMap::new();
400    /// map.insert("x-host", "hello.world".parse().unwrap());
401    ///
402    /// map.clear();
403    /// assert!(map.is_empty());
404    /// assert!(map.capacity() > 0);
405    /// ```
406    pub fn clear(&mut self) {
407        self.headers.clear();
408    }
409
410    /// Returns the number of custom metadata entries the map can hold without
411    /// reallocating.
412    ///
413    /// This number is an approximation as certain usage patterns could cause
414    /// additional allocations before the returned capacity is filled.
415    ///
416    /// # Examples
417    ///
418    /// ```
419    /// # use tonic::metadata::*;
420    /// let mut map = MetadataMap::new();
421    ///
422    /// assert_eq!(0, map.capacity());
423    ///
424    /// map.insert("x-host", "hello.world".parse().unwrap());
425    /// assert_eq!(6, map.capacity());
426    /// ```
427    pub fn capacity(&self) -> usize {
428        self.headers.capacity()
429    }
430
431    /// Reserves capacity for at least `additional` more custom metadata to be
432    /// inserted into the `MetadataMap`.
433    ///
434    /// The metadata map may reserve more space to avoid frequent reallocations.
435    /// Like with `with_capacity`, this will be a "best effort" to avoid
436    /// allocations until `additional` more custom metadata is inserted. Certain
437    /// usage patterns could cause additional allocations before the number is
438    /// reached.
439    ///
440    /// # Panics
441    ///
442    /// Panics if the new allocation size overflows `usize`.
443    ///
444    /// # Examples
445    ///
446    /// ```
447    /// # use tonic::metadata::*;
448    /// let mut map = MetadataMap::new();
449    /// map.reserve(10);
450    /// # map.insert("x-host", "bar".parse().unwrap());
451    /// ```
452    pub fn reserve(&mut self, additional: usize) {
453        self.headers.reserve(additional);
454    }
455
456    /// Returns a reference to the value associated with the key. This method
457    /// is for ascii metadata entries (those whose names don't end with
458    /// "-bin"). For binary entries, use get_bin.
459    ///
460    /// If there are multiple values associated with the key, then the first one
461    /// is returned. Use `get_all` to get all values associated with a given
462    /// key. Returns `None` if there are no values associated with the key.
463    ///
464    /// # Examples
465    ///
466    /// ```
467    /// # use tonic::metadata::*;
468    /// let mut map = MetadataMap::new();
469    /// assert!(map.get("x-host").is_none());
470    ///
471    /// map.insert("x-host", "hello".parse().unwrap());
472    /// assert_eq!(map.get("x-host").unwrap(), &"hello");
473    /// assert_eq!(map.get("x-host").unwrap(), &"hello");
474    ///
475    /// map.append("x-host", "world".parse().unwrap());
476    /// assert_eq!(map.get("x-host").unwrap(), &"hello");
477    ///
478    /// // Attempting to read a key of the wrong type fails by not
479    /// // finding anything.
480    /// map.append_bin("host-bin", MetadataValue::from_bytes(b"world"));
481    /// assert!(map.get("host-bin").is_none());
482    /// assert!(map.get("host-bin".to_string()).is_none());
483    /// assert!(map.get(&("host-bin".to_string())).is_none());
484    ///
485    /// // Attempting to read an invalid key string fails by not
486    /// // finding anything.
487    /// assert!(map.get("host{}bin").is_none());
488    /// assert!(map.get("host{}bin".to_string()).is_none());
489    /// assert!(map.get(&("host{}bin".to_string())).is_none());
490    /// ```
491    pub fn get<K>(&self, key: K) -> Option<&MetadataValue<Ascii>>
492    where
493        K: AsMetadataKey<Ascii>,
494    {
495        key.get(self)
496    }
497
498    /// Like get, but for Binary keys (for example "trace-proto-bin").
499    ///
500    /// # Examples
501    ///
502    /// ```
503    /// # use tonic::metadata::*;
504    /// let mut map = MetadataMap::new();
505    /// assert!(map.get_bin("trace-proto-bin").is_none());
506    ///
507    /// map.insert_bin("trace-proto-bin", MetadataValue::from_bytes(b"hello"));
508    /// assert_eq!(map.get_bin("trace-proto-bin").unwrap(), &"hello");
509    /// assert_eq!(map.get_bin("trace-proto-bin").unwrap(), &"hello");
510    ///
511    /// map.append_bin("trace-proto-bin", MetadataValue::from_bytes(b"world"));
512    /// assert_eq!(map.get_bin("trace-proto-bin").unwrap(), &"hello");
513    ///
514    /// // Attempting to read a key of the wrong type fails by not
515    /// // finding anything.
516    /// map.append("host", "world".parse().unwrap());
517    /// assert!(map.get_bin("host").is_none());
518    /// assert!(map.get_bin("host".to_string()).is_none());
519    /// assert!(map.get_bin(&("host".to_string())).is_none());
520    ///
521    /// // Attempting to read an invalid key string fails by not
522    /// // finding anything.
523    /// assert!(map.get_bin("host{}-bin").is_none());
524    /// assert!(map.get_bin("host{}-bin".to_string()).is_none());
525    /// assert!(map.get_bin(&("host{}-bin".to_string())).is_none());
526    /// ```
527    pub fn get_bin<K>(&self, key: K) -> Option<&MetadataValue<Binary>>
528    where
529        K: AsMetadataKey<Binary>,
530    {
531        key.get(self)
532    }
533
534    /// Returns a mutable reference to the value associated with the key. This
535    /// method is for ascii metadata entries (those whose names don't end with
536    /// "-bin"). For binary entries, use get_mut_bin.
537    ///
538    /// If there are multiple values associated with the key, then the first one
539    /// is returned. Use `entry` to get all values associated with a given
540    /// key. Returns `None` if there are no values associated with the key.
541    ///
542    /// # Examples
543    ///
544    /// ```
545    /// # use tonic::metadata::*;
546    /// let mut map = MetadataMap::default();
547    /// map.insert("x-host", "hello".parse().unwrap());
548    /// map.get_mut("x-host").unwrap().set_sensitive(true);
549    ///
550    /// assert!(map.get("x-host").unwrap().is_sensitive());
551    ///
552    /// // Attempting to read a key of the wrong type fails by not
553    /// // finding anything.
554    /// map.append_bin("host-bin", MetadataValue::from_bytes(b"world"));
555    /// assert!(map.get_mut("host-bin").is_none());
556    /// assert!(map.get_mut("host-bin".to_string()).is_none());
557    /// assert!(map.get_mut(&("host-bin".to_string())).is_none());
558    ///
559    /// // Attempting to read an invalid key string fails by not
560    /// // finding anything.
561    /// assert!(map.get_mut("host{}").is_none());
562    /// assert!(map.get_mut("host{}".to_string()).is_none());
563    /// assert!(map.get_mut(&("host{}".to_string())).is_none());
564    /// ```
565    pub fn get_mut<K>(&mut self, key: K) -> Option<&mut MetadataValue<Ascii>>
566    where
567        K: AsMetadataKey<Ascii>,
568    {
569        key.get_mut(self)
570    }
571
572    /// Like get_mut, but for Binary keys (for example "trace-proto-bin").
573    ///
574    /// # Examples
575    ///
576    /// ```
577    /// # use tonic::metadata::*;
578    /// let mut map = MetadataMap::default();
579    /// map.insert_bin("trace-proto-bin", MetadataValue::from_bytes(b"hello"));
580    /// map.get_bin_mut("trace-proto-bin").unwrap().set_sensitive(true);
581    ///
582    /// assert!(map.get_bin("trace-proto-bin").unwrap().is_sensitive());
583    ///
584    /// // Attempting to read a key of the wrong type fails by not
585    /// // finding anything.
586    /// map.append("host", "world".parse().unwrap());
587    /// assert!(map.get_bin_mut("host").is_none());
588    /// assert!(map.get_bin_mut("host".to_string()).is_none());
589    /// assert!(map.get_bin_mut(&("host".to_string())).is_none());
590    ///
591    /// // Attempting to read an invalid key string fails by not
592    /// // finding anything.
593    /// assert!(map.get_bin_mut("host{}-bin").is_none());
594    /// assert!(map.get_bin_mut("host{}-bin".to_string()).is_none());
595    /// assert!(map.get_bin_mut(&("host{}-bin".to_string())).is_none());
596    /// ```
597    pub fn get_bin_mut<K>(&mut self, key: K) -> Option<&mut MetadataValue<Binary>>
598    where
599        K: AsMetadataKey<Binary>,
600    {
601        key.get_mut(self)
602    }
603
604    /// Returns a view of all values associated with a key. This method is for
605    /// ascii metadata entries (those whose names don't end with "-bin"). For
606    /// binary entries, use get_all_bin.
607    ///
608    /// The returned view does not incur any allocations and allows iterating
609    /// the values associated with the key.  See [`GetAll`] for more details.
610    /// Returns `None` if there are no values associated with the key.
611    ///
612    /// [`GetAll`]: struct.GetAll.html
613    ///
614    /// # Examples
615    ///
616    /// ```
617    /// # use tonic::metadata::*;
618    /// let mut map = MetadataMap::new();
619    ///
620    /// map.insert("x-host", "hello".parse().unwrap());
621    /// map.append("x-host", "goodbye".parse().unwrap());
622    ///
623    /// {
624    ///     let view = map.get_all("x-host");
625    ///
626    ///     let mut iter = view.iter();
627    ///     assert_eq!(&"hello", iter.next().unwrap());
628    ///     assert_eq!(&"goodbye", iter.next().unwrap());
629    ///     assert!(iter.next().is_none());
630    /// }
631    ///
632    /// // Attempting to read a key of the wrong type fails by not
633    /// // finding anything.
634    /// map.append_bin("host-bin", MetadataValue::from_bytes(b"world"));
635    /// assert!(map.get_all("host-bin").iter().next().is_none());
636    /// assert!(map.get_all("host-bin".to_string()).iter().next().is_none());
637    /// assert!(map.get_all(&("host-bin".to_string())).iter().next().is_none());
638    ///
639    /// // Attempting to read an invalid key string fails by not
640    /// // finding anything.
641    /// assert!(map.get_all("host{}").iter().next().is_none());
642    /// assert!(map.get_all("host{}".to_string()).iter().next().is_none());
643    /// assert!(map.get_all(&("host{}".to_string())).iter().next().is_none());
644    /// ```
645    pub fn get_all<K>(&self, key: K) -> GetAll<'_, Ascii>
646    where
647        K: AsMetadataKey<Ascii>,
648    {
649        GetAll {
650            inner: key.get_all(self),
651            phantom: PhantomData,
652        }
653    }
654
655    /// Like get_all, but for Binary keys (for example "trace-proto-bin").
656    ///
657    /// # Examples
658    ///
659    /// ```
660    /// # use tonic::metadata::*;
661    /// let mut map = MetadataMap::new();
662    ///
663    /// map.insert_bin("trace-proto-bin", MetadataValue::from_bytes(b"hello"));
664    /// map.append_bin("trace-proto-bin", MetadataValue::from_bytes(b"goodbye"));
665    ///
666    /// {
667    ///     let view = map.get_all_bin("trace-proto-bin");
668    ///
669    ///     let mut iter = view.iter();
670    ///     assert_eq!(&"hello", iter.next().unwrap());
671    ///     assert_eq!(&"goodbye", iter.next().unwrap());
672    ///     assert!(iter.next().is_none());
673    /// }
674    ///
675    /// // Attempting to read a key of the wrong type fails by not
676    /// // finding anything.
677    /// map.append("host", "world".parse().unwrap());
678    /// assert!(map.get_all_bin("host").iter().next().is_none());
679    /// assert!(map.get_all_bin("host".to_string()).iter().next().is_none());
680    /// assert!(map.get_all_bin(&("host".to_string())).iter().next().is_none());
681    ///
682    /// // Attempting to read an invalid key string fails by not
683    /// // finding anything.
684    /// assert!(map.get_all_bin("host{}-bin").iter().next().is_none());
685    /// assert!(map.get_all_bin("host{}-bin".to_string()).iter().next().is_none());
686    /// assert!(map.get_all_bin(&("host{}-bin".to_string())).iter().next().is_none());
687    /// ```
688    pub fn get_all_bin<K>(&self, key: K) -> GetAll<'_, Binary>
689    where
690        K: AsMetadataKey<Binary>,
691    {
692        GetAll {
693            inner: key.get_all(self),
694            phantom: PhantomData,
695        }
696    }
697
698    /// Returns true if the map contains a value for the specified key. This
699    /// method works for both ascii and binary entries.
700    ///
701    /// # Examples
702    ///
703    /// ```
704    /// # use tonic::metadata::*;
705    /// let mut map = MetadataMap::new();
706    /// assert!(!map.contains_key("x-host"));
707    ///
708    /// map.append_bin("host-bin", MetadataValue::from_bytes(b"world"));
709    /// map.insert("x-host", "world".parse().unwrap());
710    ///
711    /// // contains_key works for both Binary and Ascii keys:
712    /// assert!(map.contains_key("x-host"));
713    /// assert!(map.contains_key("host-bin"));
714    ///
715    /// // contains_key returns false for invalid keys:
716    /// assert!(!map.contains_key("x{}host"));
717    /// ```
718    pub fn contains_key<K>(&self, key: K) -> bool
719    where
720        K: AsEncodingAgnosticMetadataKey,
721    {
722        key.contains_key(self)
723    }
724
725    /// An iterator visiting all key-value pairs (both ascii and binary).
726    ///
727    /// The iteration order is arbitrary, but consistent across platforms for
728    /// the same crate version. Each key will be yielded once per associated
729    /// value. So, if a key has 3 associated values, it will be yielded 3 times.
730    ///
731    /// # Examples
732    ///
733    /// ```
734    /// # use tonic::metadata::*;
735    /// let mut map = MetadataMap::new();
736    ///
737    /// map.insert("x-word", "hello".parse().unwrap());
738    /// map.append("x-word", "goodbye".parse().unwrap());
739    /// map.insert("x-number", "123".parse().unwrap());
740    ///
741    /// for key_and_value in map.iter() {
742    ///     match key_and_value {
743    ///         KeyAndValueRef::Ascii(ref key, ref value) =>
744    ///             println!("Ascii: {:?}: {:?}", key, value),
745    ///         KeyAndValueRef::Binary(ref key, ref value) =>
746    ///             println!("Binary: {:?}: {:?}", key, value),
747    ///     }
748    /// }
749    /// ```
750    pub fn iter(&self) -> Iter<'_> {
751        Iter {
752            inner: self.headers.iter(),
753        }
754    }
755
756    /// An iterator visiting all key-value pairs, with mutable value references.
757    ///
758    /// The iterator order is arbitrary, but consistent across platforms for the
759    /// same crate version. Each key will be yielded once per associated value,
760    /// so if a key has 3 associated values, it will be yielded 3 times.
761    ///
762    /// # Examples
763    ///
764    /// ```
765    /// # use tonic::metadata::*;
766    /// let mut map = MetadataMap::new();
767    ///
768    /// map.insert("x-word", "hello".parse().unwrap());
769    /// map.append("x-word", "goodbye".parse().unwrap());
770    /// map.insert("x-number", "123".parse().unwrap());
771    ///
772    /// for key_and_value in map.iter_mut() {
773    ///     match key_and_value {
774    ///         KeyAndMutValueRef::Ascii(key, mut value) =>
775    ///             value.set_sensitive(true),
776    ///         KeyAndMutValueRef::Binary(key, mut value) =>
777    ///             value.set_sensitive(false),
778    ///     }
779    /// }
780    /// ```
781    pub fn iter_mut(&mut self) -> IterMut<'_> {
782        IterMut {
783            inner: self.headers.iter_mut(),
784        }
785    }
786
787    /// An iterator visiting all keys.
788    ///
789    /// The iteration order is arbitrary, but consistent across platforms for
790    /// the same crate version. Each key will be yielded only once even if it
791    /// has multiple associated values.
792    ///
793    /// # Examples
794    ///
795    /// ```
796    /// # use tonic::metadata::*;
797    /// let mut map = MetadataMap::new();
798    ///
799    /// map.insert("x-word", "hello".parse().unwrap());
800    /// map.append("x-word", "goodbye".parse().unwrap());
801    /// map.insert_bin("x-number-bin", MetadataValue::from_bytes(b"123"));
802    ///
803    /// for key in map.keys() {
804    ///     match key {
805    ///         KeyRef::Ascii(ref key) =>
806    ///             println!("Ascii key: {:?}", key),
807    ///         KeyRef::Binary(ref key) =>
808    ///             println!("Binary key: {:?}", key),
809    ///     }
810    ///     println!("{:?}", key);
811    /// }
812    /// ```
813    pub fn keys(&self) -> Keys<'_> {
814        Keys {
815            inner: self.headers.keys(),
816        }
817    }
818
819    /// An iterator visiting all values (both ascii and binary).
820    ///
821    /// The iteration order is arbitrary, but consistent across platforms for
822    /// the same crate version.
823    ///
824    /// # Examples
825    ///
826    /// ```
827    /// # use tonic::metadata::*;
828    /// let mut map = MetadataMap::new();
829    ///
830    /// map.insert("x-word", "hello".parse().unwrap());
831    /// map.append("x-word", "goodbye".parse().unwrap());
832    /// map.insert_bin("x-number-bin", MetadataValue::from_bytes(b"123"));
833    ///
834    /// for value in map.values() {
835    ///     match value {
836    ///         ValueRef::Ascii(ref value) =>
837    ///             println!("Ascii value: {:?}", value),
838    ///         ValueRef::Binary(ref value) =>
839    ///             println!("Binary value: {:?}", value),
840    ///     }
841    ///     println!("{:?}", value);
842    /// }
843    /// ```
844    pub fn values(&self) -> Values<'_> {
845        Values {
846            inner: self.headers.iter(),
847        }
848    }
849
850    /// An iterator visiting all values mutably.
851    ///
852    /// The iteration order is arbitrary, but consistent across platforms for
853    /// the same crate version.
854    ///
855    /// # Examples
856    ///
857    /// ```
858    /// # use tonic::metadata::*;
859    /// let mut map = MetadataMap::default();
860    ///
861    /// map.insert("x-word", "hello".parse().unwrap());
862    /// map.append("x-word", "goodbye".parse().unwrap());
863    /// map.insert("x-number", "123".parse().unwrap());
864    ///
865    /// for value in map.values_mut() {
866    ///     match value {
867    ///         ValueRefMut::Ascii(mut value) =>
868    ///             value.set_sensitive(true),
869    ///         ValueRefMut::Binary(mut value) =>
870    ///             value.set_sensitive(false),
871    ///     }
872    /// }
873    /// ```
874    pub fn values_mut(&mut self) -> ValuesMut<'_> {
875        ValuesMut {
876            inner: self.headers.iter_mut(),
877        }
878    }
879
880    /// Gets the given ascii key's corresponding entry in the map for in-place
881    /// manipulation. For binary keys, use `entry_bin`.
882    ///
883    /// # Examples
884    ///
885    /// ```
886    /// # use tonic::metadata::*;
887    /// let mut map = MetadataMap::default();
888    ///
889    /// let headers = &[
890    ///     "content-length",
891    ///     "x-hello",
892    ///     "Content-Length",
893    ///     "x-world",
894    /// ];
895    ///
896    /// for &header in headers {
897    ///     let counter = map.entry(header).unwrap().or_insert("".parse().unwrap());
898    ///     *counter = format!("{}{}", counter.to_str().unwrap(), "1").parse().unwrap();
899    /// }
900    ///
901    /// assert_eq!(map.get("content-length").unwrap(), "11");
902    /// assert_eq!(map.get("x-hello").unwrap(), "1");
903    ///
904    /// // Gracefully handles parting invalid key strings
905    /// assert!(!map.entry("a{}b").is_ok());
906    ///
907    /// // Attempting to read a key of the wrong type fails by not
908    /// // finding anything.
909    /// map.append_bin("host-bin", MetadataValue::from_bytes(b"world"));
910    /// assert!(!map.entry("host-bin").is_ok());
911    /// assert!(!map.entry("host-bin".to_string()).is_ok());
912    /// assert!(!map.entry(&("host-bin".to_string())).is_ok());
913    ///
914    /// // Attempting to read an invalid key string fails by not
915    /// // finding anything.
916    /// assert!(!map.entry("host{}").is_ok());
917    /// assert!(!map.entry("host{}".to_string()).is_ok());
918    /// assert!(!map.entry(&("host{}".to_string())).is_ok());
919    /// ```
920    pub fn entry<K>(&mut self, key: K) -> Result<Entry<'_, Ascii>, InvalidMetadataKey>
921    where
922        K: AsMetadataKey<Ascii>,
923    {
924        self.generic_entry::<Ascii, K>(key)
925    }
926
927    /// Gets the given Binary key's corresponding entry in the map for in-place
928    /// manipulation.
929    ///
930    /// # Examples
931    ///
932    /// ```
933    /// # use tonic::metadata::*;
934    /// # use std::str;
935    /// let mut map = MetadataMap::default();
936    ///
937    /// let headers = &[
938    ///     "content-length-bin",
939    ///     "x-hello-bin",
940    ///     "Content-Length-bin",
941    ///     "x-world-bin",
942    /// ];
943    ///
944    /// for &header in headers {
945    ///     let counter = map.entry_bin(header).unwrap().or_insert(MetadataValue::from_bytes(b""));
946    ///     *counter = MetadataValue::from_bytes(format!("{}{}", str::from_utf8(counter.to_bytes().unwrap().as_ref()).unwrap(), "1").as_bytes());
947    /// }
948    ///
949    /// assert_eq!(map.get_bin("content-length-bin").unwrap(), "11");
950    /// assert_eq!(map.get_bin("x-hello-bin").unwrap(), "1");
951    ///
952    /// // Attempting to read a key of the wrong type fails by not
953    /// // finding anything.
954    /// map.append("host", "world".parse().unwrap());
955    /// assert!(!map.entry_bin("host").is_ok());
956    /// assert!(!map.entry_bin("host".to_string()).is_ok());
957    /// assert!(!map.entry_bin(&("host".to_string())).is_ok());
958    ///
959    /// // Attempting to read an invalid key string fails by not
960    /// // finding anything.
961    /// assert!(!map.entry_bin("host{}-bin").is_ok());
962    /// assert!(!map.entry_bin("host{}-bin".to_string()).is_ok());
963    /// assert!(!map.entry_bin(&("host{}-bin".to_string())).is_ok());
964    /// ```
965    pub fn entry_bin<K>(&mut self, key: K) -> Result<Entry<'_, Binary>, InvalidMetadataKey>
966    where
967        K: AsMetadataKey<Binary>,
968    {
969        self.generic_entry::<Binary, K>(key)
970    }
971
972    fn generic_entry<VE: ValueEncoding, K>(
973        &mut self,
974        key: K,
975    ) -> Result<Entry<'_, VE>, InvalidMetadataKey>
976    where
977        K: AsMetadataKey<VE>,
978    {
979        match key.entry(self) {
980            Ok(entry) => Ok(match entry {
981                http::header::Entry::Occupied(e) => Entry::Occupied(OccupiedEntry {
982                    inner: e,
983                    phantom: PhantomData,
984                }),
985                http::header::Entry::Vacant(e) => Entry::Vacant(VacantEntry {
986                    inner: e,
987                    phantom: PhantomData,
988                }),
989            }),
990            Err(err) => Err(err),
991        }
992    }
993
994    /// Inserts an ascii key-value pair into the map. To insert a binary entry,
995    /// use `insert_bin`.
996    ///
997    /// This method panics when the given key is a string and it cannot be
998    /// converted to a `MetadataKey<Ascii>`.
999    ///
1000    /// If the map did not previously have this key present, then `None` is
1001    /// returned.
1002    ///
1003    /// If the map did have this key present, the new value is associated with
1004    /// the key and all previous values are removed. **Note** that only a single
1005    /// one of the previous values is returned. If there are multiple values
1006    /// that have been previously associated with the key, then the first one is
1007    /// returned. See `insert_mult` on `OccupiedEntry` for an API that returns
1008    /// all values.
1009    ///
1010    /// The key is not updated, though; this matters for types that can be `==`
1011    /// without being identical.
1012    ///
1013    /// # Examples
1014    ///
1015    /// ```
1016    /// # use tonic::metadata::*;
1017    /// let mut map = MetadataMap::new();
1018    /// assert!(map.insert("x-host", "world".parse().unwrap()).is_none());
1019    /// assert!(!map.is_empty());
1020    ///
1021    /// let mut prev = map.insert("x-host", "earth".parse().unwrap()).unwrap();
1022    /// assert_eq!("world", prev);
1023    /// ```
1024    ///
1025    /// ```should_panic
1026    /// # use tonic::metadata::*;
1027    /// let mut map = MetadataMap::new();
1028    /// // Trying to insert a key that is not valid panics.
1029    /// map.insert("x{}host", "world".parse().unwrap());
1030    /// ```
1031    ///
1032    /// ```should_panic
1033    /// # use tonic::metadata::*;
1034    /// let mut map = MetadataMap::new();
1035    /// // Trying to insert a key that is binary panics (use insert_bin).
1036    /// map.insert("x-host-bin", "world".parse().unwrap());
1037    /// ```
1038    pub fn insert<K>(&mut self, key: K, val: MetadataValue<Ascii>) -> Option<MetadataValue<Ascii>>
1039    where
1040        K: IntoMetadataKey<Ascii>,
1041    {
1042        key.insert(self, val)
1043    }
1044
1045    /// Like insert, but for Binary keys (for example "trace-proto-bin").
1046    ///
1047    /// This method panics when the given key is a string and it cannot be
1048    /// converted to a `MetadataKey<Binary>`.
1049    ///
1050    /// # Examples
1051    ///
1052    /// ```
1053    /// # use tonic::metadata::*;
1054    /// let mut map = MetadataMap::new();
1055    /// assert!(map.insert_bin("trace-proto-bin", MetadataValue::from_bytes(b"world")).is_none());
1056    /// assert!(!map.is_empty());
1057    ///
1058    /// let mut prev = map.insert_bin("trace-proto-bin", MetadataValue::from_bytes(b"earth")).unwrap();
1059    /// assert_eq!("world", prev);
1060    /// ```
1061    ///
1062    /// ```should_panic
1063    /// # use tonic::metadata::*;
1064    /// let mut map = MetadataMap::default();
1065    /// // Attempting to add a binary metadata entry with an invalid name
1066    /// map.insert_bin("trace-proto", MetadataValue::from_bytes(b"hello")); // This line panics!
1067    /// ```
1068    ///
1069    /// ```should_panic
1070    /// # use tonic::metadata::*;
1071    /// let mut map = MetadataMap::new();
1072    /// // Trying to insert a key that is not valid panics.
1073    /// map.insert_bin("x{}host-bin", MetadataValue::from_bytes(b"world")); // This line panics!
1074    /// ```
1075    pub fn insert_bin<K>(
1076        &mut self,
1077        key: K,
1078        val: MetadataValue<Binary>,
1079    ) -> Option<MetadataValue<Binary>>
1080    where
1081        K: IntoMetadataKey<Binary>,
1082    {
1083        key.insert(self, val)
1084    }
1085
1086    /// Inserts an ascii key-value pair into the map. To insert a binary entry,
1087    /// use `append_bin`.
1088    ///
1089    /// This method panics when the given key is a string and it cannot be
1090    /// converted to a `MetadataKey<Ascii>`.
1091    ///
1092    /// If the map did not previously have this key present, then `false` is
1093    /// returned.
1094    ///
1095    /// If the map did have this key present, the new value is pushed to the end
1096    /// of the list of values currently associated with the key. The key is not
1097    /// updated, though; this matters for types that can be `==` without being
1098    /// identical.
1099    ///
1100    /// # Examples
1101    ///
1102    /// ```
1103    /// # use tonic::metadata::*;
1104    /// let mut map = MetadataMap::new();
1105    /// assert!(map.insert("x-host", "world".parse().unwrap()).is_none());
1106    /// assert!(!map.is_empty());
1107    ///
1108    /// map.append("x-host", "earth".parse().unwrap());
1109    ///
1110    /// let values = map.get_all("x-host");
1111    /// let mut i = values.iter();
1112    /// assert_eq!("world", *i.next().unwrap());
1113    /// assert_eq!("earth", *i.next().unwrap());
1114    /// ```
1115    ///
1116    /// ```should_panic
1117    /// # use tonic::metadata::*;
1118    /// let mut map = MetadataMap::new();
1119    /// // Trying to append a key that is not valid panics.
1120    /// map.append("x{}host", "world".parse().unwrap()); // This line panics!
1121    /// ```
1122    ///
1123    /// ```should_panic
1124    /// # use tonic::metadata::*;
1125    /// let mut map = MetadataMap::new();
1126    /// // Trying to append a key that is binary panics (use append_bin).
1127    /// map.append("x-host-bin", "world".parse().unwrap()); // This line panics!
1128    /// ```
1129    pub fn append<K>(&mut self, key: K, value: MetadataValue<Ascii>) -> bool
1130    where
1131        K: IntoMetadataKey<Ascii>,
1132    {
1133        key.append(self, value)
1134    }
1135
1136    /// Like append, but for binary keys (for example "trace-proto-bin").
1137    ///
1138    /// This method panics when the given key is a string and it cannot be
1139    /// converted to a `MetadataKey<Binary>`.
1140    ///
1141    /// # Examples
1142    ///
1143    /// ```
1144    /// # use tonic::metadata::*;
1145    /// let mut map = MetadataMap::new();
1146    /// assert!(map.insert_bin("trace-proto-bin", MetadataValue::from_bytes(b"world")).is_none());
1147    /// assert!(!map.is_empty());
1148    ///
1149    /// map.append_bin("trace-proto-bin", MetadataValue::from_bytes(b"earth"));
1150    ///
1151    /// let values = map.get_all_bin("trace-proto-bin");
1152    /// let mut i = values.iter();
1153    /// assert_eq!("world", *i.next().unwrap());
1154    /// assert_eq!("earth", *i.next().unwrap());
1155    /// ```
1156    ///
1157    /// ```should_panic
1158    /// # use tonic::metadata::*;
1159    /// let mut map = MetadataMap::new();
1160    /// // Trying to append a key that is not valid panics.
1161    /// map.append_bin("x{}host-bin", MetadataValue::from_bytes(b"world")); // This line panics!
1162    /// ```
1163    ///
1164    /// ```should_panic
1165    /// # use tonic::metadata::*;
1166    /// let mut map = MetadataMap::new();
1167    /// // Trying to append a key that is ascii panics (use append).
1168    /// map.append_bin("x-host", MetadataValue::from_bytes(b"world")); // This line panics!
1169    /// ```
1170    pub fn append_bin<K>(&mut self, key: K, value: MetadataValue<Binary>) -> bool
1171    where
1172        K: IntoMetadataKey<Binary>,
1173    {
1174        key.append(self, value)
1175    }
1176
1177    /// Removes an ascii key from the map, returning the value associated with
1178    /// the key. To remove a binary key, use `remove_bin`.
1179    ///
1180    /// Returns `None` if the map does not contain the key. If there are
1181    /// multiple values associated with the key, then the first one is returned.
1182    /// See `remove_entry_mult` on `OccupiedEntry` for an API that yields all
1183    /// values.
1184    ///
1185    /// # Examples
1186    ///
1187    /// ```
1188    /// # use tonic::metadata::*;
1189    /// let mut map = MetadataMap::new();
1190    /// map.insert("x-host", "hello.world".parse().unwrap());
1191    ///
1192    /// let prev = map.remove("x-host").unwrap();
1193    /// assert_eq!("hello.world", prev);
1194    ///
1195    /// assert!(map.remove("x-host").is_none());
1196    ///
1197    /// // Attempting to remove a key of the wrong type fails by not
1198    /// // finding anything.
1199    /// map.append_bin("host-bin", MetadataValue::from_bytes(b"world"));
1200    /// assert!(map.remove("host-bin").is_none());
1201    /// assert!(map.remove("host-bin".to_string()).is_none());
1202    /// assert!(map.remove(&("host-bin".to_string())).is_none());
1203    ///
1204    /// // Attempting to remove an invalid key string fails by not
1205    /// // finding anything.
1206    /// assert!(map.remove("host{}").is_none());
1207    /// assert!(map.remove("host{}".to_string()).is_none());
1208    /// assert!(map.remove(&("host{}".to_string())).is_none());
1209    /// ```
1210    pub fn remove<K>(&mut self, key: K) -> Option<MetadataValue<Ascii>>
1211    where
1212        K: AsMetadataKey<Ascii>,
1213    {
1214        key.remove(self)
1215    }
1216
1217    /// Like remove, but for Binary keys (for example "trace-proto-bin").
1218    ///
1219    /// # Examples
1220    ///
1221    /// ```
1222    /// # use tonic::metadata::*;
1223    /// let mut map = MetadataMap::new();
1224    /// map.insert_bin("trace-proto-bin", MetadataValue::from_bytes(b"hello.world"));
1225    ///
1226    /// let prev = map.remove_bin("trace-proto-bin").unwrap();
1227    /// assert_eq!("hello.world", prev);
1228    ///
1229    /// assert!(map.remove_bin("trace-proto-bin").is_none());
1230    ///
1231    /// // Attempting to remove a key of the wrong type fails by not
1232    /// // finding anything.
1233    /// map.append("host", "world".parse().unwrap());
1234    /// assert!(map.remove_bin("host").is_none());
1235    /// assert!(map.remove_bin("host".to_string()).is_none());
1236    /// assert!(map.remove_bin(&("host".to_string())).is_none());
1237    ///
1238    /// // Attempting to remove an invalid key string fails by not
1239    /// // finding anything.
1240    /// assert!(map.remove_bin("host{}-bin").is_none());
1241    /// assert!(map.remove_bin("host{}-bin".to_string()).is_none());
1242    /// assert!(map.remove_bin(&("host{}-bin".to_string())).is_none());
1243    /// ```
1244    pub fn remove_bin<K>(&mut self, key: K) -> Option<MetadataValue<Binary>>
1245    where
1246        K: AsMetadataKey<Binary>,
1247    {
1248        key.remove(self)
1249    }
1250
1251    pub(crate) fn merge(&mut self, other: MetadataMap) {
1252        self.headers.extend(other.headers);
1253    }
1254}
1255
1256// ===== impl Iter =====
1257
1258impl<'a> Iterator for Iter<'a> {
1259    type Item = KeyAndValueRef<'a>;
1260
1261    fn next(&mut self) -> Option<Self::Item> {
1262        self.inner.next().map(|item| {
1263            let (name, value) = item;
1264            if Ascii::is_valid_key(name.as_str()) {
1265                KeyAndValueRef::Ascii(
1266                    MetadataKey::unchecked_from_header_name_ref(name),
1267                    MetadataValue::unchecked_from_header_value_ref(value),
1268                )
1269            } else {
1270                KeyAndValueRef::Binary(
1271                    MetadataKey::unchecked_from_header_name_ref(name),
1272                    MetadataValue::unchecked_from_header_value_ref(value),
1273                )
1274            }
1275        })
1276    }
1277
1278    fn size_hint(&self) -> (usize, Option<usize>) {
1279        self.inner.size_hint()
1280    }
1281}
1282
1283// ===== impl IterMut =====
1284
1285impl<'a> Iterator for IterMut<'a> {
1286    type Item = KeyAndMutValueRef<'a>;
1287
1288    fn next(&mut self) -> Option<Self::Item> {
1289        self.inner.next().map(|item| {
1290            let (name, value) = item;
1291            if Ascii::is_valid_key(name.as_str()) {
1292                KeyAndMutValueRef::Ascii(
1293                    MetadataKey::unchecked_from_header_name_ref(name),
1294                    MetadataValue::unchecked_from_mut_header_value_ref(value),
1295                )
1296            } else {
1297                KeyAndMutValueRef::Binary(
1298                    MetadataKey::unchecked_from_header_name_ref(name),
1299                    MetadataValue::unchecked_from_mut_header_value_ref(value),
1300                )
1301            }
1302        })
1303    }
1304
1305    fn size_hint(&self) -> (usize, Option<usize>) {
1306        self.inner.size_hint()
1307    }
1308}
1309
1310// ===== impl ValueDrain =====
1311
1312impl<VE: ValueEncoding> Iterator for ValueDrain<'_, VE> {
1313    type Item = MetadataValue<VE>;
1314
1315    fn next(&mut self) -> Option<Self::Item> {
1316        self.inner
1317            .next()
1318            .map(MetadataValue::unchecked_from_header_value)
1319    }
1320
1321    fn size_hint(&self) -> (usize, Option<usize>) {
1322        self.inner.size_hint()
1323    }
1324}
1325
1326// ===== impl Keys =====
1327
1328impl<'a> Iterator for Keys<'a> {
1329    type Item = KeyRef<'a>;
1330
1331    fn next(&mut self) -> Option<Self::Item> {
1332        self.inner.next().map(|key| {
1333            if Ascii::is_valid_key(key.as_str()) {
1334                KeyRef::Ascii(MetadataKey::unchecked_from_header_name_ref(key))
1335            } else {
1336                KeyRef::Binary(MetadataKey::unchecked_from_header_name_ref(key))
1337            }
1338        })
1339    }
1340
1341    fn size_hint(&self) -> (usize, Option<usize>) {
1342        self.inner.size_hint()
1343    }
1344}
1345
1346impl ExactSizeIterator for Keys<'_> {}
1347
1348// ===== impl Values ====
1349
1350impl<'a> Iterator for Values<'a> {
1351    type Item = ValueRef<'a>;
1352
1353    fn next(&mut self) -> Option<Self::Item> {
1354        self.inner.next().map(|item| {
1355            let (name, value) = item;
1356            if Ascii::is_valid_key(name.as_str()) {
1357                ValueRef::Ascii(MetadataValue::unchecked_from_header_value_ref(value))
1358            } else {
1359                ValueRef::Binary(MetadataValue::unchecked_from_header_value_ref(value))
1360            }
1361        })
1362    }
1363
1364    fn size_hint(&self) -> (usize, Option<usize>) {
1365        self.inner.size_hint()
1366    }
1367}
1368
1369// ===== impl Values ====
1370
1371impl<'a> Iterator for ValuesMut<'a> {
1372    type Item = ValueRefMut<'a>;
1373
1374    fn next(&mut self) -> Option<Self::Item> {
1375        self.inner.next().map(|item| {
1376            let (name, value) = item;
1377            if Ascii::is_valid_key(name.as_str()) {
1378                ValueRefMut::Ascii(MetadataValue::unchecked_from_mut_header_value_ref(value))
1379            } else {
1380                ValueRefMut::Binary(MetadataValue::unchecked_from_mut_header_value_ref(value))
1381            }
1382        })
1383    }
1384
1385    fn size_hint(&self) -> (usize, Option<usize>) {
1386        self.inner.size_hint()
1387    }
1388}
1389
1390// ===== impl ValueIter =====
1391
1392impl<'a, VE: ValueEncoding> Iterator for ValueIter<'a, VE>
1393where
1394    VE: 'a,
1395{
1396    type Item = &'a MetadataValue<VE>;
1397
1398    fn next(&mut self) -> Option<Self::Item> {
1399        match self.inner {
1400            Some(ref mut inner) => inner
1401                .next()
1402                .map(MetadataValue::unchecked_from_header_value_ref),
1403            None => None,
1404        }
1405    }
1406
1407    fn size_hint(&self) -> (usize, Option<usize>) {
1408        match self.inner {
1409            Some(ref inner) => inner.size_hint(),
1410            None => (0, Some(0)),
1411        }
1412    }
1413}
1414
1415impl<'a, VE: ValueEncoding> DoubleEndedIterator for ValueIter<'a, VE>
1416where
1417    VE: 'a,
1418{
1419    fn next_back(&mut self) -> Option<Self::Item> {
1420        match self.inner {
1421            Some(ref mut inner) => inner
1422                .next_back()
1423                .map(MetadataValue::unchecked_from_header_value_ref),
1424            None => None,
1425        }
1426    }
1427}
1428
1429// ===== impl ValueIterMut =====
1430
1431impl<'a, VE: ValueEncoding> Iterator for ValueIterMut<'a, VE>
1432where
1433    VE: 'a,
1434{
1435    type Item = &'a mut MetadataValue<VE>;
1436
1437    fn next(&mut self) -> Option<Self::Item> {
1438        self.inner
1439            .next()
1440            .map(MetadataValue::unchecked_from_mut_header_value_ref)
1441    }
1442}
1443
1444impl<'a, VE: ValueEncoding> DoubleEndedIterator for ValueIterMut<'a, VE>
1445where
1446    VE: 'a,
1447{
1448    fn next_back(&mut self) -> Option<Self::Item> {
1449        self.inner
1450            .next_back()
1451            .map(MetadataValue::unchecked_from_mut_header_value_ref)
1452    }
1453}
1454
1455// ===== impl Entry =====
1456
1457impl<'a, VE: ValueEncoding> Entry<'a, VE> {
1458    /// Ensures a value is in the entry by inserting the default if empty.
1459    ///
1460    /// Returns a mutable reference to the **first** value in the entry.
1461    ///
1462    /// # Examples
1463    ///
1464    /// ```
1465    /// # use tonic::metadata::*;
1466    /// let mut map: MetadataMap = MetadataMap::default();
1467    ///
1468    /// let keys = &[
1469    ///     "content-length",
1470    ///     "x-hello",
1471    ///     "Content-Length",
1472    ///     "x-world",
1473    /// ];
1474    ///
1475    /// for &key in keys {
1476    ///     let counter = map.entry(key)
1477    ///         .expect("valid key names")
1478    ///         .or_insert("".parse().unwrap());
1479    ///     *counter = format!("{}{}", counter.to_str().unwrap(), "1").parse().unwrap();
1480    /// }
1481    ///
1482    /// assert_eq!(map.get("content-length").unwrap(), "11");
1483    /// assert_eq!(map.get("x-hello").unwrap(), "1");
1484    /// ```
1485    pub fn or_insert(self, default: MetadataValue<VE>) -> &'a mut MetadataValue<VE> {
1486        use self::Entry::*;
1487
1488        match self {
1489            Occupied(e) => e.into_mut(),
1490            Vacant(e) => e.insert(default),
1491        }
1492    }
1493
1494    /// Ensures a value is in the entry by inserting the result of the default
1495    /// function if empty.
1496    ///
1497    /// The default function is not called if the entry exists in the map.
1498    /// Returns a mutable reference to the **first** value in the entry.
1499    ///
1500    /// # Examples
1501    ///
1502    /// Basic usage.
1503    ///
1504    /// ```
1505    /// # use tonic::metadata::*;
1506    /// let mut map = MetadataMap::new();
1507    ///
1508    /// let res = map.entry("x-hello").unwrap()
1509    ///     .or_insert_with(|| "world".parse().unwrap());
1510    ///
1511    /// assert_eq!(res, "world");
1512    /// ```
1513    ///
1514    /// The default function is not called if the entry exists in the map.
1515    ///
1516    /// ```
1517    /// # use tonic::metadata::*;
1518    /// let mut map = MetadataMap::new();
1519    /// map.insert("host", "world".parse().unwrap());
1520    ///
1521    /// let res = map.entry("host")
1522    ///     .expect("host is a valid string")
1523    ///     .or_insert_with(|| unreachable!());
1524    ///
1525    ///
1526    /// assert_eq!(res, "world");
1527    /// ```
1528    pub fn or_insert_with<F: FnOnce() -> MetadataValue<VE>>(
1529        self,
1530        default: F,
1531    ) -> &'a mut MetadataValue<VE> {
1532        use self::Entry::*;
1533
1534        match self {
1535            Occupied(e) => e.into_mut(),
1536            Vacant(e) => e.insert(default()),
1537        }
1538    }
1539
1540    /// Returns a reference to the entry's key
1541    ///
1542    /// # Examples
1543    ///
1544    /// ```
1545    /// # use tonic::metadata::*;
1546    /// let mut map = MetadataMap::new();
1547    ///
1548    /// assert_eq!(map.entry("x-hello").unwrap().key(), "x-hello");
1549    /// ```
1550    pub fn key(&self) -> &MetadataKey<VE> {
1551        use self::Entry::*;
1552
1553        MetadataKey::unchecked_from_header_name_ref(match *self {
1554            Vacant(ref e) => e.inner.key(),
1555            Occupied(ref e) => e.inner.key(),
1556        })
1557    }
1558}
1559
1560// ===== impl VacantEntry =====
1561
1562impl<'a, VE: ValueEncoding> VacantEntry<'a, VE> {
1563    /// Returns a reference to the entry's key
1564    ///
1565    /// # Examples
1566    ///
1567    /// ```
1568    /// # use tonic::metadata::*;
1569    /// let mut map = MetadataMap::new();
1570    ///
1571    /// assert_eq!(map.entry("x-hello").unwrap().key(), "x-hello");
1572    /// ```
1573    pub fn key(&self) -> &MetadataKey<VE> {
1574        MetadataKey::unchecked_from_header_name_ref(self.inner.key())
1575    }
1576
1577    /// Take ownership of the key
1578    ///
1579    /// # Examples
1580    ///
1581    /// ```
1582    /// # use tonic::metadata::*;
1583    /// let mut map = MetadataMap::new();
1584    ///
1585    /// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
1586    ///     assert_eq!(v.into_key().as_str(), "x-hello");
1587    /// }
1588    /// ```
1589    pub fn into_key(self) -> MetadataKey<VE> {
1590        MetadataKey::unchecked_from_header_name(self.inner.into_key())
1591    }
1592
1593    /// Insert the value into the entry.
1594    ///
1595    /// The value will be associated with this entry's key. A mutable reference
1596    /// to the inserted value will be returned.
1597    ///
1598    /// # Examples
1599    ///
1600    /// ```
1601    /// # use tonic::metadata::*;
1602    /// let mut map = MetadataMap::new();
1603    ///
1604    /// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
1605    ///     v.insert("world".parse().unwrap());
1606    /// }
1607    ///
1608    /// assert_eq!(map.get("x-hello").unwrap(), "world");
1609    /// ```
1610    pub fn insert(self, value: MetadataValue<VE>) -> &'a mut MetadataValue<VE> {
1611        MetadataValue::unchecked_from_mut_header_value_ref(self.inner.insert(value.inner))
1612    }
1613
1614    /// Insert the value into the entry.
1615    ///
1616    /// The value will be associated with this entry's key. The new
1617    /// `OccupiedEntry` is returned, allowing for further manipulation.
1618    ///
1619    /// # Examples
1620    ///
1621    /// ```
1622    /// # use tonic::metadata::*;
1623    /// let mut map = MetadataMap::new();
1624    ///
1625    /// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
1626    ///     let mut e = v.insert_entry("world".parse().unwrap());
1627    ///     e.insert("world2".parse().unwrap());
1628    /// }
1629    ///
1630    /// assert_eq!(map.get("x-hello").unwrap(), "world2");
1631    /// ```
1632    pub fn insert_entry(self, value: MetadataValue<VE>) -> OccupiedEntry<'a, Ascii> {
1633        OccupiedEntry {
1634            inner: self.inner.insert_entry(value.inner),
1635            phantom: PhantomData,
1636        }
1637    }
1638}
1639
1640// ===== impl OccupiedEntry =====
1641
1642impl<'a, VE: ValueEncoding> OccupiedEntry<'a, VE> {
1643    /// Returns a reference to the entry's key.
1644    ///
1645    /// # Examples
1646    ///
1647    /// ```
1648    /// # use tonic::metadata::*;
1649    /// let mut map = MetadataMap::new();
1650    /// map.insert("host", "world".parse().unwrap());
1651    ///
1652    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
1653    ///     assert_eq!("host", e.key());
1654    /// }
1655    /// ```
1656    pub fn key(&self) -> &MetadataKey<VE> {
1657        MetadataKey::unchecked_from_header_name_ref(self.inner.key())
1658    }
1659
1660    /// Get a reference to the first value in the entry.
1661    ///
1662    /// Values are stored in insertion order.
1663    ///
1664    /// # Panics
1665    ///
1666    /// `get` panics if there are no values associated with the entry.
1667    ///
1668    /// # Examples
1669    ///
1670    /// ```
1671    /// # use tonic::metadata::*;
1672    /// let mut map = MetadataMap::new();
1673    /// map.insert("host", "hello.world".parse().unwrap());
1674    ///
1675    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
1676    ///     assert_eq!(e.get(), &"hello.world");
1677    ///
1678    ///     e.append("hello.earth".parse().unwrap());
1679    ///
1680    ///     assert_eq!(e.get(), &"hello.world");
1681    /// }
1682    /// ```
1683    pub fn get(&self) -> &MetadataValue<VE> {
1684        MetadataValue::unchecked_from_header_value_ref(self.inner.get())
1685    }
1686
1687    /// Get a mutable reference to the first value in the entry.
1688    ///
1689    /// Values are stored in insertion order.
1690    ///
1691    /// # Panics
1692    ///
1693    /// `get_mut` panics if there are no values associated with the entry.
1694    ///
1695    /// # Examples
1696    ///
1697    /// ```
1698    /// # use tonic::metadata::*;
1699    /// let mut map = MetadataMap::default();
1700    /// map.insert("host", "hello.world".parse().unwrap());
1701    ///
1702    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
1703    ///     e.get_mut().set_sensitive(true);
1704    ///     assert_eq!(e.get(), &"hello.world");
1705    ///     assert!(e.get().is_sensitive());
1706    /// }
1707    /// ```
1708    pub fn get_mut(&mut self) -> &mut MetadataValue<VE> {
1709        MetadataValue::unchecked_from_mut_header_value_ref(self.inner.get_mut())
1710    }
1711
1712    /// Converts the `OccupiedEntry` into a mutable reference to the **first**
1713    /// value.
1714    ///
1715    /// The lifetime of the returned reference is bound to the original map.
1716    ///
1717    /// # Panics
1718    ///
1719    /// `into_mut` panics if there are no values associated with the entry.
1720    ///
1721    /// # Examples
1722    ///
1723    /// ```
1724    /// # use tonic::metadata::*;
1725    /// let mut map = MetadataMap::default();
1726    /// map.insert("host", "hello.world".parse().unwrap());
1727    /// map.append("host", "hello.earth".parse().unwrap());
1728    ///
1729    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
1730    ///     e.into_mut().set_sensitive(true);
1731    /// }
1732    ///
1733    /// assert!(map.get("host").unwrap().is_sensitive());
1734    /// ```
1735    pub fn into_mut(self) -> &'a mut MetadataValue<VE> {
1736        MetadataValue::unchecked_from_mut_header_value_ref(self.inner.into_mut())
1737    }
1738
1739    /// Sets the value of the entry.
1740    ///
1741    /// All previous values associated with the entry are removed and the first
1742    /// one is returned. See `insert_mult` for an API that returns all values.
1743    ///
1744    /// # Examples
1745    ///
1746    /// ```
1747    /// # use tonic::metadata::*;
1748    /// let mut map = MetadataMap::new();
1749    /// map.insert("host", "hello.world".parse().unwrap());
1750    ///
1751    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
1752    ///     let mut prev = e.insert("earth".parse().unwrap());
1753    ///     assert_eq!("hello.world", prev);
1754    /// }
1755    ///
1756    /// assert_eq!("earth", map.get("host").unwrap());
1757    /// ```
1758    pub fn insert(&mut self, value: MetadataValue<VE>) -> MetadataValue<VE> {
1759        let header_value = self.inner.insert(value.inner);
1760        MetadataValue::unchecked_from_header_value(header_value)
1761    }
1762
1763    /// Sets the value of the entry.
1764    ///
1765    /// This function does the same as `insert` except it returns an iterator
1766    /// that yields all values previously associated with the key.
1767    ///
1768    /// # Examples
1769    ///
1770    /// ```
1771    /// # use tonic::metadata::*;
1772    /// let mut map = MetadataMap::new();
1773    /// map.insert("host", "world".parse().unwrap());
1774    /// map.append("host", "world2".parse().unwrap());
1775    ///
1776    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
1777    ///     let mut prev = e.insert_mult("earth".parse().unwrap());
1778    ///     assert_eq!("world", prev.next().unwrap());
1779    ///     assert_eq!("world2", prev.next().unwrap());
1780    ///     assert!(prev.next().is_none());
1781    /// }
1782    ///
1783    /// assert_eq!("earth", map.get("host").unwrap());
1784    /// ```
1785    pub fn insert_mult(&mut self, value: MetadataValue<VE>) -> ValueDrain<'_, VE> {
1786        ValueDrain {
1787            inner: self.inner.insert_mult(value.inner),
1788            phantom: PhantomData,
1789        }
1790    }
1791
1792    /// Insert the value into the entry.
1793    ///
1794    /// The new value is appended to the end of the entry's value list. All
1795    /// previous values associated with the entry are retained.
1796    ///
1797    /// # Examples
1798    ///
1799    /// ```
1800    /// # use tonic::metadata::*;
1801    /// let mut map = MetadataMap::new();
1802    /// map.insert("host", "world".parse().unwrap());
1803    ///
1804    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
1805    ///     e.append("earth".parse().unwrap());
1806    /// }
1807    ///
1808    /// let values = map.get_all("host");
1809    /// let mut i = values.iter();
1810    /// assert_eq!("world", *i.next().unwrap());
1811    /// assert_eq!("earth", *i.next().unwrap());
1812    /// ```
1813    pub fn append(&mut self, value: MetadataValue<VE>) {
1814        self.inner.append(value.inner)
1815    }
1816
1817    /// Remove the entry from the map.
1818    ///
1819    /// All values associated with the entry are removed and the first one is
1820    /// returned. See `remove_entry_mult` for an API that returns all values.
1821    ///
1822    /// # Examples
1823    ///
1824    /// ```
1825    /// # use tonic::metadata::*;
1826    /// let mut map = MetadataMap::new();
1827    /// map.insert("host", "world".parse().unwrap());
1828    ///
1829    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
1830    ///     let mut prev = e.remove();
1831    ///     assert_eq!("world", prev);
1832    /// }
1833    ///
1834    /// assert!(!map.contains_key("host"));
1835    /// ```
1836    pub fn remove(self) -> MetadataValue<VE> {
1837        let value = self.inner.remove();
1838        MetadataValue::unchecked_from_header_value(value)
1839    }
1840
1841    /// Remove the entry from the map.
1842    ///
1843    /// The key and all values associated with the entry are removed and the
1844    /// first one is returned. See `remove_entry_mult` for an API that returns
1845    /// all values.
1846    ///
1847    /// # Examples
1848    ///
1849    /// ```
1850    /// # use tonic::metadata::*;
1851    /// let mut map = MetadataMap::new();
1852    /// map.insert("host", "world".parse().unwrap());
1853    ///
1854    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
1855    ///     let (key, mut prev) = e.remove_entry();
1856    ///     assert_eq!("host", key.as_str());
1857    ///     assert_eq!("world", prev);
1858    /// }
1859    ///
1860    /// assert!(!map.contains_key("host"));
1861    /// ```
1862    pub fn remove_entry(self) -> (MetadataKey<VE>, MetadataValue<VE>) {
1863        let (name, value) = self.inner.remove_entry();
1864        (
1865            MetadataKey::unchecked_from_header_name(name),
1866            MetadataValue::unchecked_from_header_value(value),
1867        )
1868    }
1869
1870    /// Remove the entry from the map.
1871    ///
1872    /// The key and all values associated with the entry are removed and
1873    /// returned.
1874    pub fn remove_entry_mult(self) -> (MetadataKey<VE>, ValueDrain<'a, VE>) {
1875        let (name, value_drain) = self.inner.remove_entry_mult();
1876        (
1877            MetadataKey::unchecked_from_header_name(name),
1878            ValueDrain {
1879                inner: value_drain,
1880                phantom: PhantomData,
1881            },
1882        )
1883    }
1884
1885    /// Returns an iterator visiting all values associated with the entry.
1886    ///
1887    /// Values are iterated in insertion order.
1888    ///
1889    /// # Examples
1890    ///
1891    /// ```
1892    /// # use tonic::metadata::*;
1893    /// let mut map = MetadataMap::new();
1894    /// map.insert("host", "world".parse().unwrap());
1895    /// map.append("host", "earth".parse().unwrap());
1896    ///
1897    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
1898    ///     let mut iter = e.iter();
1899    ///     assert_eq!(&"world", iter.next().unwrap());
1900    ///     assert_eq!(&"earth", iter.next().unwrap());
1901    ///     assert!(iter.next().is_none());
1902    /// }
1903    /// ```
1904    pub fn iter(&self) -> ValueIter<'_, VE> {
1905        ValueIter {
1906            inner: Some(self.inner.iter()),
1907            phantom: PhantomData,
1908        }
1909    }
1910
1911    /// Returns an iterator mutably visiting all values associated with the
1912    /// entry.
1913    ///
1914    /// Values are iterated in insertion order.
1915    ///
1916    /// # Examples
1917    ///
1918    /// ```
1919    /// # use tonic::metadata::*;
1920    /// let mut map = MetadataMap::default();
1921    /// map.insert("host", "world".parse().unwrap());
1922    /// map.append("host", "earth".parse().unwrap());
1923    ///
1924    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
1925    ///     for e in e.iter_mut() {
1926    ///         e.set_sensitive(true);
1927    ///     }
1928    /// }
1929    ///
1930    /// let mut values = map.get_all("host");
1931    /// let mut i = values.iter();
1932    /// assert!(i.next().unwrap().is_sensitive());
1933    /// assert!(i.next().unwrap().is_sensitive());
1934    /// ```
1935    pub fn iter_mut(&mut self) -> ValueIterMut<'_, VE> {
1936        ValueIterMut {
1937            inner: self.inner.iter_mut(),
1938            phantom: PhantomData,
1939        }
1940    }
1941}
1942
1943impl<'a, VE: ValueEncoding> IntoIterator for OccupiedEntry<'a, VE>
1944where
1945    VE: 'a,
1946{
1947    type Item = &'a mut MetadataValue<VE>;
1948    type IntoIter = ValueIterMut<'a, VE>;
1949
1950    fn into_iter(self) -> ValueIterMut<'a, VE> {
1951        ValueIterMut {
1952            inner: self.inner.into_iter(),
1953            phantom: PhantomData,
1954        }
1955    }
1956}
1957
1958impl<'a, 'b: 'a, VE: ValueEncoding> IntoIterator for &'b OccupiedEntry<'a, VE> {
1959    type Item = &'a MetadataValue<VE>;
1960    type IntoIter = ValueIter<'a, VE>;
1961
1962    fn into_iter(self) -> ValueIter<'a, VE> {
1963        self.iter()
1964    }
1965}
1966
1967impl<'a, 'b: 'a, VE: ValueEncoding> IntoIterator for &'b mut OccupiedEntry<'a, VE> {
1968    type Item = &'a mut MetadataValue<VE>;
1969    type IntoIter = ValueIterMut<'a, VE>;
1970
1971    fn into_iter(self) -> ValueIterMut<'a, VE> {
1972        self.iter_mut()
1973    }
1974}
1975
1976// ===== impl GetAll =====
1977
1978impl<'a, VE: ValueEncoding> GetAll<'a, VE> {
1979    /// Returns an iterator visiting all values associated with the entry.
1980    ///
1981    /// Values are iterated in insertion order.
1982    ///
1983    /// # Examples
1984    ///
1985    /// ```
1986    /// # use tonic::metadata::*;
1987    /// let mut map = MetadataMap::new();
1988    /// map.insert("x-host", "hello.world".parse().unwrap());
1989    /// map.append("x-host", "hello.earth".parse().unwrap());
1990    ///
1991    /// let values = map.get_all("x-host");
1992    /// let mut iter = values.iter();
1993    /// assert_eq!(&"hello.world", iter.next().unwrap());
1994    /// assert_eq!(&"hello.earth", iter.next().unwrap());
1995    /// assert!(iter.next().is_none());
1996    /// ```
1997    pub fn iter(&self) -> ValueIter<'a, VE> {
1998        ValueIter {
1999            inner: self.inner.as_ref().map(|inner| inner.iter()),
2000            phantom: PhantomData,
2001        }
2002    }
2003}
2004
2005impl<VE: ValueEncoding> PartialEq for GetAll<'_, VE> {
2006    fn eq(&self, other: &Self) -> bool {
2007        self.inner.iter().eq(other.inner.iter())
2008    }
2009}
2010
2011impl<'a, VE: ValueEncoding> IntoIterator for GetAll<'a, VE>
2012where
2013    VE: 'a,
2014{
2015    type Item = &'a MetadataValue<VE>;
2016    type IntoIter = ValueIter<'a, VE>;
2017
2018    fn into_iter(self) -> ValueIter<'a, VE> {
2019        ValueIter {
2020            inner: self.inner.map(|inner| inner.into_iter()),
2021            phantom: PhantomData,
2022        }
2023    }
2024}
2025
2026impl<'a, 'b: 'a, VE: ValueEncoding> IntoIterator for &'b GetAll<'a, VE> {
2027    type Item = &'a MetadataValue<VE>;
2028    type IntoIter = ValueIter<'a, VE>;
2029
2030    fn into_iter(self) -> ValueIter<'a, VE> {
2031        ValueIter {
2032            inner: self.inner.as_ref().map(|inner| inner.into_iter()),
2033            phantom: PhantomData,
2034        }
2035    }
2036}
2037
2038// ===== impl IntoMetadataKey / AsMetadataKey =====
2039
2040mod into_metadata_key {
2041    use super::{MetadataMap, MetadataValue, ValueEncoding};
2042    use crate::metadata::key::MetadataKey;
2043
2044    /// A marker trait used to identify values that can be used as insert keys
2045    /// to a `MetadataMap`.
2046    pub trait IntoMetadataKey<VE: ValueEncoding>: Sealed<VE> {}
2047
2048    // All methods are on this pub(super) trait, instead of `IntoMetadataKey`,
2049    // so that they aren't publicly exposed to the world.
2050    //
2051    // Being on the `IntoMetadataKey` trait would mean users could call
2052    // `"host".insert(&mut map, "localhost")`.
2053    //
2054    // Ultimately, this allows us to adjust the signatures of these methods
2055    // without breaking any external crate.
2056    pub trait Sealed<VE: ValueEncoding> {
2057        #[doc(hidden)]
2058        fn insert(self, map: &mut MetadataMap, val: MetadataValue<VE>)
2059        -> Option<MetadataValue<VE>>;
2060
2061        #[doc(hidden)]
2062        fn append(self, map: &mut MetadataMap, val: MetadataValue<VE>) -> bool;
2063    }
2064
2065    // ==== impls ====
2066
2067    impl<VE: ValueEncoding> Sealed<VE> for MetadataKey<VE> {
2068        #[doc(hidden)]
2069        #[inline]
2070        fn insert(
2071            self,
2072            map: &mut MetadataMap,
2073            val: MetadataValue<VE>,
2074        ) -> Option<MetadataValue<VE>> {
2075            map.headers
2076                .insert(self.inner, val.inner)
2077                .map(MetadataValue::unchecked_from_header_value)
2078        }
2079
2080        #[doc(hidden)]
2081        #[inline]
2082        fn append(self, map: &mut MetadataMap, val: MetadataValue<VE>) -> bool {
2083            map.headers.append(self.inner, val.inner)
2084        }
2085    }
2086
2087    impl<VE: ValueEncoding> IntoMetadataKey<VE> for MetadataKey<VE> {}
2088
2089    impl<VE: ValueEncoding> Sealed<VE> for &MetadataKey<VE> {
2090        #[doc(hidden)]
2091        #[inline]
2092        fn insert(
2093            self,
2094            map: &mut MetadataMap,
2095            val: MetadataValue<VE>,
2096        ) -> Option<MetadataValue<VE>> {
2097            map.headers
2098                .insert(&self.inner, val.inner)
2099                .map(MetadataValue::unchecked_from_header_value)
2100        }
2101        #[doc(hidden)]
2102        #[inline]
2103        fn append(self, map: &mut MetadataMap, val: MetadataValue<VE>) -> bool {
2104            map.headers.append(&self.inner, val.inner)
2105        }
2106    }
2107
2108    impl<VE: ValueEncoding> IntoMetadataKey<VE> for &MetadataKey<VE> {}
2109
2110    impl<VE: ValueEncoding> Sealed<VE> for &'static str {
2111        #[doc(hidden)]
2112        #[inline]
2113        fn insert(
2114            self,
2115            map: &mut MetadataMap,
2116            val: MetadataValue<VE>,
2117        ) -> Option<MetadataValue<VE>> {
2118            // Perform name validation
2119            let key = MetadataKey::<VE>::from_static(self);
2120
2121            map.headers
2122                .insert(key.inner, val.inner)
2123                .map(MetadataValue::unchecked_from_header_value)
2124        }
2125        #[doc(hidden)]
2126        #[inline]
2127        fn append(self, map: &mut MetadataMap, val: MetadataValue<VE>) -> bool {
2128            // Perform name validation
2129            let key = MetadataKey::<VE>::from_static(self);
2130
2131            map.headers.append(key.inner, val.inner)
2132        }
2133    }
2134
2135    impl<VE: ValueEncoding> IntoMetadataKey<VE> for &'static str {}
2136}
2137
2138mod as_metadata_key {
2139    use super::{MetadataMap, MetadataValue, ValueEncoding};
2140    use crate::metadata::key::{InvalidMetadataKey, MetadataKey};
2141    use http::header::{Entry, GetAll, HeaderValue};
2142
2143    /// A marker trait used to identify values that can be used as search keys
2144    /// to a `MetadataMap`.
2145    pub trait AsMetadataKey<VE: ValueEncoding>: Sealed<VE> {}
2146
2147    // All methods are on this pub(super) trait, instead of `AsMetadataKey`,
2148    // so that they aren't publicly exposed to the world.
2149    //
2150    // Being on the `AsMetadataKey` trait would mean users could call
2151    // `"host".find(&map)`.
2152    //
2153    // Ultimately, this allows us to adjust the signatures of these methods
2154    // without breaking any external crate.
2155    pub trait Sealed<VE: ValueEncoding> {
2156        #[doc(hidden)]
2157        fn get(self, map: &MetadataMap) -> Option<&MetadataValue<VE>>;
2158
2159        #[doc(hidden)]
2160        fn get_mut(self, map: &mut MetadataMap) -> Option<&mut MetadataValue<VE>>;
2161
2162        #[doc(hidden)]
2163        fn get_all(self, map: &MetadataMap) -> Option<GetAll<'_, HeaderValue>>;
2164
2165        #[doc(hidden)]
2166        fn entry(self, map: &mut MetadataMap)
2167        -> Result<Entry<'_, HeaderValue>, InvalidMetadataKey>;
2168
2169        #[doc(hidden)]
2170        fn remove(self, map: &mut MetadataMap) -> Option<MetadataValue<VE>>;
2171    }
2172
2173    // ==== impls ====
2174
2175    impl<VE: ValueEncoding> Sealed<VE> for MetadataKey<VE> {
2176        #[doc(hidden)]
2177        #[inline]
2178        fn get(self, map: &MetadataMap) -> Option<&MetadataValue<VE>> {
2179            map.headers
2180                .get(self.inner)
2181                .map(MetadataValue::unchecked_from_header_value_ref)
2182        }
2183
2184        #[doc(hidden)]
2185        #[inline]
2186        fn get_mut(self, map: &mut MetadataMap) -> Option<&mut MetadataValue<VE>> {
2187            map.headers
2188                .get_mut(self.inner)
2189                .map(MetadataValue::unchecked_from_mut_header_value_ref)
2190        }
2191
2192        #[doc(hidden)]
2193        #[inline]
2194        fn get_all(self, map: &MetadataMap) -> Option<GetAll<'_, HeaderValue>> {
2195            Some(map.headers.get_all(self.inner))
2196        }
2197
2198        #[doc(hidden)]
2199        #[inline]
2200        fn entry(
2201            self,
2202            map: &mut MetadataMap,
2203        ) -> Result<Entry<'_, HeaderValue>, InvalidMetadataKey> {
2204            Ok(map.headers.entry(self.inner))
2205        }
2206
2207        #[doc(hidden)]
2208        #[inline]
2209        fn remove(self, map: &mut MetadataMap) -> Option<MetadataValue<VE>> {
2210            map.headers
2211                .remove(self.inner)
2212                .map(MetadataValue::unchecked_from_header_value)
2213        }
2214    }
2215
2216    impl<VE: ValueEncoding> AsMetadataKey<VE> for MetadataKey<VE> {}
2217
2218    impl<VE: ValueEncoding> Sealed<VE> for &MetadataKey<VE> {
2219        #[doc(hidden)]
2220        #[inline]
2221        fn get(self, map: &MetadataMap) -> Option<&MetadataValue<VE>> {
2222            map.headers
2223                .get(&self.inner)
2224                .map(MetadataValue::unchecked_from_header_value_ref)
2225        }
2226
2227        #[doc(hidden)]
2228        #[inline]
2229        fn get_mut(self, map: &mut MetadataMap) -> Option<&mut MetadataValue<VE>> {
2230            map.headers
2231                .get_mut(&self.inner)
2232                .map(MetadataValue::unchecked_from_mut_header_value_ref)
2233        }
2234
2235        #[doc(hidden)]
2236        #[inline]
2237        fn get_all(self, map: &MetadataMap) -> Option<GetAll<'_, HeaderValue>> {
2238            Some(map.headers.get_all(&self.inner))
2239        }
2240
2241        #[doc(hidden)]
2242        #[inline]
2243        fn entry(
2244            self,
2245            map: &mut MetadataMap,
2246        ) -> Result<Entry<'_, HeaderValue>, InvalidMetadataKey> {
2247            Ok(map.headers.entry(&self.inner))
2248        }
2249
2250        #[doc(hidden)]
2251        #[inline]
2252        fn remove(self, map: &mut MetadataMap) -> Option<MetadataValue<VE>> {
2253            map.headers
2254                .remove(&self.inner)
2255                .map(MetadataValue::unchecked_from_header_value)
2256        }
2257    }
2258
2259    impl<VE: ValueEncoding> AsMetadataKey<VE> for &MetadataKey<VE> {}
2260
2261    impl<VE: ValueEncoding> Sealed<VE> for &str {
2262        #[doc(hidden)]
2263        #[inline]
2264        fn get(self, map: &MetadataMap) -> Option<&MetadataValue<VE>> {
2265            if !VE::is_valid_key(self) {
2266                return None;
2267            }
2268            map.headers
2269                .get(self)
2270                .map(MetadataValue::unchecked_from_header_value_ref)
2271        }
2272
2273        #[doc(hidden)]
2274        #[inline]
2275        fn get_mut(self, map: &mut MetadataMap) -> Option<&mut MetadataValue<VE>> {
2276            if !VE::is_valid_key(self) {
2277                return None;
2278            }
2279            map.headers
2280                .get_mut(self)
2281                .map(MetadataValue::unchecked_from_mut_header_value_ref)
2282        }
2283
2284        #[doc(hidden)]
2285        #[inline]
2286        fn get_all(self, map: &MetadataMap) -> Option<GetAll<'_, HeaderValue>> {
2287            if !VE::is_valid_key(self) {
2288                return None;
2289            }
2290            Some(map.headers.get_all(self))
2291        }
2292
2293        #[doc(hidden)]
2294        #[inline]
2295        fn entry(
2296            self,
2297            map: &mut MetadataMap,
2298        ) -> Result<Entry<'_, HeaderValue>, InvalidMetadataKey> {
2299            if !VE::is_valid_key(self) {
2300                return Err(InvalidMetadataKey::new());
2301            }
2302
2303            let key = http::header::HeaderName::from_bytes(self.as_bytes())
2304                .map_err(|_| InvalidMetadataKey::new())?;
2305            let entry = map.headers.entry(key);
2306            Ok(entry)
2307        }
2308
2309        #[doc(hidden)]
2310        #[inline]
2311        fn remove(self, map: &mut MetadataMap) -> Option<MetadataValue<VE>> {
2312            if !VE::is_valid_key(self) {
2313                return None;
2314            }
2315            map.headers
2316                .remove(self)
2317                .map(MetadataValue::unchecked_from_header_value)
2318        }
2319    }
2320
2321    impl<VE: ValueEncoding> AsMetadataKey<VE> for &str {}
2322
2323    impl<VE: ValueEncoding> Sealed<VE> for String {
2324        #[doc(hidden)]
2325        #[inline]
2326        fn get(self, map: &MetadataMap) -> Option<&MetadataValue<VE>> {
2327            if !VE::is_valid_key(self.as_str()) {
2328                return None;
2329            }
2330            map.headers
2331                .get(self.as_str())
2332                .map(MetadataValue::unchecked_from_header_value_ref)
2333        }
2334
2335        #[doc(hidden)]
2336        #[inline]
2337        fn get_mut(self, map: &mut MetadataMap) -> Option<&mut MetadataValue<VE>> {
2338            if !VE::is_valid_key(self.as_str()) {
2339                return None;
2340            }
2341            map.headers
2342                .get_mut(self.as_str())
2343                .map(MetadataValue::unchecked_from_mut_header_value_ref)
2344        }
2345
2346        #[doc(hidden)]
2347        #[inline]
2348        fn get_all(self, map: &MetadataMap) -> Option<GetAll<'_, HeaderValue>> {
2349            if !VE::is_valid_key(self.as_str()) {
2350                return None;
2351            }
2352            Some(map.headers.get_all(self.as_str()))
2353        }
2354
2355        #[doc(hidden)]
2356        #[inline]
2357        fn entry(
2358            self,
2359            map: &mut MetadataMap,
2360        ) -> Result<Entry<'_, HeaderValue>, InvalidMetadataKey> {
2361            if !VE::is_valid_key(self.as_str()) {
2362                return Err(InvalidMetadataKey::new());
2363            }
2364
2365            let key = http::header::HeaderName::from_bytes(self.as_bytes())
2366                .map_err(|_| InvalidMetadataKey::new())?;
2367            Ok(map.headers.entry(key))
2368        }
2369
2370        #[doc(hidden)]
2371        #[inline]
2372        fn remove(self, map: &mut MetadataMap) -> Option<MetadataValue<VE>> {
2373            if !VE::is_valid_key(self.as_str()) {
2374                return None;
2375            }
2376            map.headers
2377                .remove(self.as_str())
2378                .map(MetadataValue::unchecked_from_header_value)
2379        }
2380    }
2381
2382    impl<VE: ValueEncoding> AsMetadataKey<VE> for String {}
2383
2384    impl<VE: ValueEncoding> Sealed<VE> for &String {
2385        #[doc(hidden)]
2386        #[inline]
2387        fn get(self, map: &MetadataMap) -> Option<&MetadataValue<VE>> {
2388            if !VE::is_valid_key(self) {
2389                return None;
2390            }
2391            map.headers
2392                .get(self.as_str())
2393                .map(MetadataValue::unchecked_from_header_value_ref)
2394        }
2395
2396        #[doc(hidden)]
2397        #[inline]
2398        fn get_mut(self, map: &mut MetadataMap) -> Option<&mut MetadataValue<VE>> {
2399            if !VE::is_valid_key(self) {
2400                return None;
2401            }
2402            map.headers
2403                .get_mut(self.as_str())
2404                .map(MetadataValue::unchecked_from_mut_header_value_ref)
2405        }
2406
2407        #[doc(hidden)]
2408        #[inline]
2409        fn get_all(self, map: &MetadataMap) -> Option<GetAll<'_, HeaderValue>> {
2410            if !VE::is_valid_key(self) {
2411                return None;
2412            }
2413            Some(map.headers.get_all(self.as_str()))
2414        }
2415
2416        #[doc(hidden)]
2417        #[inline]
2418        fn entry(
2419            self,
2420            map: &mut MetadataMap,
2421        ) -> Result<Entry<'_, HeaderValue>, InvalidMetadataKey> {
2422            if !VE::is_valid_key(self) {
2423                return Err(InvalidMetadataKey::new());
2424            }
2425
2426            let key = http::header::HeaderName::from_bytes(self.as_bytes())
2427                .map_err(|_| InvalidMetadataKey::new())?;
2428            Ok(map.headers.entry(key))
2429        }
2430
2431        #[doc(hidden)]
2432        #[inline]
2433        fn remove(self, map: &mut MetadataMap) -> Option<MetadataValue<VE>> {
2434            if !VE::is_valid_key(self) {
2435                return None;
2436            }
2437            map.headers
2438                .remove(self.as_str())
2439                .map(MetadataValue::unchecked_from_header_value)
2440        }
2441    }
2442
2443    impl<VE: ValueEncoding> AsMetadataKey<VE> for &String {}
2444}
2445
2446mod as_encoding_agnostic_metadata_key {
2447    use super::{MetadataMap, ValueEncoding};
2448    use crate::metadata::key::MetadataKey;
2449
2450    /// A marker trait used to identify values that can be used as search keys
2451    /// to a `MetadataMap`, for operations that don't expose the actual value.
2452    pub trait AsEncodingAgnosticMetadataKey: Sealed {}
2453
2454    // All methods are on this pub(super) trait, instead of
2455    // `AsEncodingAgnosticMetadataKey`, so that they aren't publicly exposed to
2456    // the world.
2457    //
2458    // Being on the `AsEncodingAgnosticMetadataKey` trait would mean users could
2459    // call `"host".contains_key(&map)`.
2460    //
2461    // Ultimately, this allows us to adjust the signatures of these methods
2462    // without breaking any external crate.
2463    pub trait Sealed {
2464        #[doc(hidden)]
2465        fn contains_key(&self, map: &MetadataMap) -> bool;
2466    }
2467
2468    // ==== impls ====
2469
2470    impl<VE: ValueEncoding> Sealed for MetadataKey<VE> {
2471        #[doc(hidden)]
2472        #[inline]
2473        fn contains_key(&self, map: &MetadataMap) -> bool {
2474            map.headers.contains_key(&self.inner)
2475        }
2476    }
2477
2478    impl<VE: ValueEncoding> AsEncodingAgnosticMetadataKey for MetadataKey<VE> {}
2479
2480    impl<VE: ValueEncoding> Sealed for &MetadataKey<VE> {
2481        #[doc(hidden)]
2482        #[inline]
2483        fn contains_key(&self, map: &MetadataMap) -> bool {
2484            map.headers.contains_key(&self.inner)
2485        }
2486    }
2487
2488    impl<VE: ValueEncoding> AsEncodingAgnosticMetadataKey for &MetadataKey<VE> {}
2489
2490    impl Sealed for &str {
2491        #[doc(hidden)]
2492        #[inline]
2493        fn contains_key(&self, map: &MetadataMap) -> bool {
2494            map.headers.contains_key(*self)
2495        }
2496    }
2497
2498    impl AsEncodingAgnosticMetadataKey for &str {}
2499
2500    impl Sealed for String {
2501        #[doc(hidden)]
2502        #[inline]
2503        fn contains_key(&self, map: &MetadataMap) -> bool {
2504            map.headers.contains_key(self.as_str())
2505        }
2506    }
2507
2508    impl AsEncodingAgnosticMetadataKey for String {}
2509
2510    impl Sealed for &String {
2511        #[doc(hidden)]
2512        #[inline]
2513        fn contains_key(&self, map: &MetadataMap) -> bool {
2514            map.headers.contains_key(self.as_str())
2515        }
2516    }
2517
2518    impl AsEncodingAgnosticMetadataKey for &String {}
2519}
2520
2521#[cfg(test)]
2522mod tests {
2523    use super::*;
2524
2525    #[test]
2526    fn test_from_headers_takes_http_headers() {
2527        let mut http_map = http::HeaderMap::new();
2528        http_map.insert("x-host", "example.com".parse().unwrap());
2529
2530        let map = MetadataMap::from_headers(http_map);
2531
2532        assert_eq!(map.get("x-host").unwrap(), "example.com");
2533    }
2534
2535    #[test]
2536    fn test_to_headers_encoding() {
2537        use crate::Status;
2538        let special_char_message = "Beyond 100% ascii \t\n\ršŸŒ¶ļøšŸ’‰šŸ’§šŸ®šŸŗ";
2539        let s1 = Status::unknown(special_char_message);
2540
2541        assert_eq!(s1.message(), special_char_message);
2542
2543        let s1_map = s1.to_header_map().unwrap();
2544        let s2 = Status::from_header_map(&s1_map).unwrap();
2545
2546        assert_eq!(s1.message(), s2.message());
2547
2548        assert!(
2549            s1_map
2550                .get("grpc-message")
2551                .unwrap()
2552                .to_str()
2553                .unwrap()
2554                .starts_with("Beyond%20100%25%20ascii"),
2555            "Percent sign or other character isn't encoded as desired: {:?}",
2556            s1_map.get("grpc-message")
2557        );
2558    }
2559
2560    #[test]
2561    fn test_iter_categorizes_ascii_entries() {
2562        let mut map = MetadataMap::new();
2563
2564        map.insert("x-word", "hello".parse().unwrap());
2565        map.append_bin("x-word-bin", MetadataValue::from_bytes(b"goodbye"));
2566        map.insert_bin("x-number-bin", MetadataValue::from_bytes(b"123"));
2567
2568        let mut found_x_word = false;
2569        for key_and_value in map.iter() {
2570            if let KeyAndValueRef::Ascii(key, _value) = key_and_value {
2571                if key.as_str() == "x-word" {
2572                    found_x_word = true;
2573                } else {
2574                    panic!("Unexpected key");
2575                }
2576            }
2577        }
2578        assert!(found_x_word);
2579    }
2580
2581    #[test]
2582    fn test_iter_categorizes_binary_entries() {
2583        let mut map = MetadataMap::new();
2584
2585        map.insert("x-word", "hello".parse().unwrap());
2586        map.append_bin("x-word-bin", MetadataValue::from_bytes(b"goodbye"));
2587
2588        let mut found_x_word_bin = false;
2589        for key_and_value in map.iter() {
2590            if let KeyAndValueRef::Binary(key, _value) = key_and_value {
2591                if key.as_str() == "x-word-bin" {
2592                    found_x_word_bin = true;
2593                } else {
2594                    panic!("Unexpected key");
2595                }
2596            }
2597        }
2598        assert!(found_x_word_bin);
2599    }
2600
2601    #[test]
2602    fn test_iter_mut_categorizes_ascii_entries() {
2603        let mut map = MetadataMap::new();
2604
2605        map.insert("x-word", "hello".parse().unwrap());
2606        map.append_bin("x-word-bin", MetadataValue::from_bytes(b"goodbye"));
2607        map.insert_bin("x-number-bin", MetadataValue::from_bytes(b"123"));
2608
2609        let mut found_x_word = false;
2610        for key_and_value in map.iter_mut() {
2611            if let KeyAndMutValueRef::Ascii(key, _value) = key_and_value {
2612                if key.as_str() == "x-word" {
2613                    found_x_word = true;
2614                } else {
2615                    panic!("Unexpected key");
2616                }
2617            }
2618        }
2619        assert!(found_x_word);
2620    }
2621
2622    #[test]
2623    fn test_iter_mut_categorizes_binary_entries() {
2624        let mut map = MetadataMap::new();
2625
2626        map.insert("x-word", "hello".parse().unwrap());
2627        map.append_bin("x-word-bin", MetadataValue::from_bytes(b"goodbye"));
2628
2629        let mut found_x_word_bin = false;
2630        for key_and_value in map.iter_mut() {
2631            if let KeyAndMutValueRef::Binary(key, _value) = key_and_value {
2632                if key.as_str() == "x-word-bin" {
2633                    found_x_word_bin = true;
2634                } else {
2635                    panic!("Unexpected key");
2636                }
2637            }
2638        }
2639        assert!(found_x_word_bin);
2640    }
2641
2642    #[test]
2643    fn test_keys_categorizes_ascii_entries() {
2644        let mut map = MetadataMap::new();
2645
2646        map.insert("x-word", "hello".parse().unwrap());
2647        map.append_bin("x-word-bin", MetadataValue::from_bytes(b"goodbye"));
2648        map.insert_bin("x-number-bin", MetadataValue::from_bytes(b"123"));
2649
2650        let mut found_x_word = false;
2651        for key in map.keys() {
2652            if let KeyRef::Ascii(key) = key {
2653                if key.as_str() == "x-word" {
2654                    found_x_word = true;
2655                } else {
2656                    panic!("Unexpected key");
2657                }
2658            }
2659        }
2660        assert!(found_x_word);
2661    }
2662
2663    #[test]
2664    fn test_keys_categorizes_binary_entries() {
2665        let mut map = MetadataMap::new();
2666
2667        map.insert("x-word", "hello".parse().unwrap());
2668        map.insert_bin("x-number-bin", MetadataValue::from_bytes(b"123"));
2669
2670        let mut found_x_number_bin = false;
2671        for key in map.keys() {
2672            if let KeyRef::Binary(key) = key {
2673                if key.as_str() == "x-number-bin" {
2674                    found_x_number_bin = true;
2675                } else {
2676                    panic!("Unexpected key");
2677                }
2678            }
2679        }
2680        assert!(found_x_number_bin);
2681    }
2682
2683    #[test]
2684    fn test_values_categorizes_ascii_entries() {
2685        let mut map = MetadataMap::new();
2686
2687        map.insert("x-word", "hello".parse().unwrap());
2688        map.append_bin("x-word-bin", MetadataValue::from_bytes(b"goodbye"));
2689        map.insert_bin("x-number-bin", MetadataValue::from_bytes(b"123"));
2690
2691        let mut found_x_word = false;
2692        for value in map.values() {
2693            if let ValueRef::Ascii(value) = value {
2694                if *value == "hello" {
2695                    found_x_word = true;
2696                } else {
2697                    panic!("Unexpected key");
2698                }
2699            }
2700        }
2701        assert!(found_x_word);
2702    }
2703
2704    #[test]
2705    fn test_values_categorizes_binary_entries() {
2706        let mut map = MetadataMap::new();
2707
2708        map.insert("x-word", "hello".parse().unwrap());
2709        map.append_bin("x-word-bin", MetadataValue::from_bytes(b"goodbye"));
2710
2711        let mut found_x_word_bin = false;
2712        for value_ref in map.values() {
2713            if let ValueRef::Binary(value) = value_ref {
2714                assert_eq!(*value, "goodbye");
2715                found_x_word_bin = true;
2716            }
2717        }
2718        assert!(found_x_word_bin);
2719    }
2720
2721    #[test]
2722    fn test_values_mut_categorizes_ascii_entries() {
2723        let mut map = MetadataMap::new();
2724
2725        map.insert("x-word", "hello".parse().unwrap());
2726        map.append_bin("x-word-bin", MetadataValue::from_bytes(b"goodbye"));
2727        map.insert_bin("x-number-bin", MetadataValue::from_bytes(b"123"));
2728
2729        let mut found_x_word = false;
2730        for value_ref in map.values_mut() {
2731            if let ValueRefMut::Ascii(value) = value_ref {
2732                assert_eq!(*value, "hello");
2733                found_x_word = true;
2734            }
2735        }
2736        assert!(found_x_word);
2737    }
2738
2739    #[test]
2740    fn test_values_mut_categorizes_binary_entries() {
2741        let mut map = MetadataMap::new();
2742
2743        map.insert("x-word", "hello".parse().unwrap());
2744        map.append_bin("x-word-bin", MetadataValue::from_bytes(b"goodbye"));
2745
2746        let mut found_x_word_bin = false;
2747        for value in map.values_mut() {
2748            if let ValueRefMut::Binary(value) = value {
2749                assert_eq!(*value, "goodbye");
2750                found_x_word_bin = true;
2751            }
2752        }
2753        assert!(found_x_word_bin);
2754    }
2755
2756    #[allow(dead_code)]
2757    fn value_drain_is_send_sync() {
2758        fn is_send_sync<T: Send + Sync>() {}
2759
2760        is_send_sync::<Iter<'_>>();
2761        is_send_sync::<IterMut<'_>>();
2762
2763        is_send_sync::<ValueDrain<'_, Ascii>>();
2764        is_send_sync::<ValueDrain<'_, Binary>>();
2765
2766        is_send_sync::<ValueIterMut<'_, Ascii>>();
2767        is_send_sync::<ValueIterMut<'_, Binary>>();
2768    }
2769}