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