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