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