tonic/metadata/
map.rs

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