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