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