tonic/metadata/
map.rs

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