1use super::encoding::{
26 Ascii, Binary, InvalidMetadataValue, InvalidMetadataValueBytes, ValueEncoding,
27};
28use super::key::MetadataKey;
29
30use bytes::Bytes;
31use http::header::HeaderValue;
32use std::error::Error;
33use std::hash::{Hash, Hasher};
34use std::marker::PhantomData;
35use std::str::FromStr;
36use std::{cmp, fmt};
37
38#[derive(Clone)]
45#[repr(transparent)]
46pub struct MetadataValue<VE: ValueEncoding> {
47 pub(crate) inner: HeaderValue,
50 phantom: PhantomData<VE>,
51}
52
53#[derive(Debug)]
58pub struct ToStrError {
59 _priv: (),
60}
61
62pub type AsciiMetadataValue = MetadataValue<Ascii>;
64pub type BinaryMetadataValue = MetadataValue<Binary>;
66
67impl<VE: ValueEncoding> MetadataValue<VE> {
68 #[inline]
95 pub fn from_static(src: &'static str) -> Self {
96 MetadataValue {
97 inner: VE::from_static(src),
98 phantom: PhantomData,
99 }
100 }
101
102 #[inline]
111 pub unsafe fn from_shared_unchecked(src: Bytes) -> Self {
112 unsafe {
113 MetadataValue {
114 inner: HeaderValue::from_maybe_shared_unchecked(src),
115 phantom: PhantomData,
116 }
117 }
118 }
119
120 #[inline]
133 pub fn is_empty(&self) -> bool {
134 VE::is_empty(self.inner.as_bytes())
135 }
136
137 #[inline]
155 pub fn to_bytes(&self) -> Result<Bytes, InvalidMetadataValueBytes> {
156 VE::decode(self.inner.as_bytes())
157 }
158
159 #[inline]
174 pub fn set_sensitive(&mut self, val: bool) {
175 self.inner.set_sensitive(val);
176 }
177
178 #[inline]
200 pub fn is_sensitive(&self) -> bool {
201 self.inner.is_sensitive()
202 }
203
204 #[inline]
221 pub fn as_encoded_bytes(&self) -> &[u8] {
222 self.inner.as_bytes()
223 }
224
225 #[inline]
229 pub(crate) fn unchecked_from_header_value(value: HeaderValue) -> Self {
230 MetadataValue {
231 inner: value,
232 phantom: PhantomData,
233 }
234 }
235
236 #[inline]
240 pub(crate) fn unchecked_from_header_value_ref(header_value: &HeaderValue) -> &Self {
241 unsafe { &*(header_value as *const HeaderValue as *const Self) }
242 }
243
244 #[inline]
248 pub(crate) fn unchecked_from_mut_header_value_ref(header_value: &mut HeaderValue) -> &mut Self {
249 unsafe { &mut *(header_value as *mut HeaderValue as *mut Self) }
250 }
251}
252
253impl<VE: ValueEncoding> TryFrom<&[u8]> for MetadataValue<VE> {
278 type Error = InvalidMetadataValueBytes;
279
280 #[inline]
281 fn try_from(src: &[u8]) -> Result<Self, Self::Error> {
282 VE::from_bytes(src).map(|value| MetadataValue {
283 inner: value,
284 phantom: PhantomData,
285 })
286 }
287}
288
289impl<VE: ValueEncoding, const N: usize> TryFrom<&[u8; N]> for MetadataValue<VE> {
314 type Error = InvalidMetadataValueBytes;
315
316 #[inline]
317 fn try_from(src: &[u8; N]) -> Result<Self, Self::Error> {
318 Self::try_from(src.as_ref())
319 }
320}
321
322impl<VE: ValueEncoding> TryFrom<Bytes> for MetadataValue<VE> {
333 type Error = InvalidMetadataValueBytes;
334
335 #[inline]
336 fn try_from(src: Bytes) -> Result<Self, Self::Error> {
337 VE::from_shared(src).map(|value| MetadataValue {
338 inner: value,
339 phantom: PhantomData,
340 })
341 }
342}
343
344impl<VE: ValueEncoding> TryFrom<Vec<u8>> for MetadataValue<VE> {
355 type Error = InvalidMetadataValueBytes;
356
357 #[inline]
358 fn try_from(src: Vec<u8>) -> Result<Self, Self::Error> {
359 Self::try_from(src.as_slice())
360 }
361}
362
363impl<'a> TryFrom<&'a str> for MetadataValue<Ascii> {
370 type Error = InvalidMetadataValue;
371
372 #[inline]
373 fn try_from(s: &'a str) -> Result<Self, Self::Error> {
374 s.parse()
375 }
376}
377
378impl<'a> TryFrom<&'a String> for MetadataValue<Ascii> {
385 type Error = InvalidMetadataValue;
386
387 #[inline]
388 fn try_from(s: &'a String) -> Result<Self, Self::Error> {
389 s.parse()
390 }
391}
392
393impl TryFrom<String> for MetadataValue<Ascii> {
400 type Error = InvalidMetadataValue;
401
402 #[inline]
403 fn try_from(s: String) -> Result<Self, Self::Error> {
404 s.parse()
405 }
406}
407
408impl MetadataValue<Ascii> {
409 #[inline]
422 pub fn from_key<KeyVE: ValueEncoding>(key: MetadataKey<KeyVE>) -> Self {
423 key.into()
424 }
425
426 #[inline]
441 pub fn len(&self) -> usize {
442 self.inner.len()
443 }
444
445 pub fn to_str(&self) -> Result<&str, ToStrError> {
459 self.inner.to_str().map_err(|_| ToStrError::new())
460 }
461
462 #[inline]
473 pub fn as_bytes(&self) -> &[u8] {
474 self.inner.as_bytes()
475 }
476}
477
478impl MetadataValue<Binary> {
479 #[inline]
489 pub fn from_bytes(src: &[u8]) -> Self {
490 Self::try_from(src).unwrap()
492 }
493}
494
495impl<VE: ValueEncoding> AsRef<[u8]> for MetadataValue<VE> {
496 #[inline]
497 fn as_ref(&self) -> &[u8] {
498 self.inner.as_ref()
499 }
500}
501
502impl<VE: ValueEncoding> fmt::Debug for MetadataValue<VE> {
503 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
504 VE::fmt(&self.inner, f)
505 }
506}
507
508impl<KeyVE: ValueEncoding> From<MetadataKey<KeyVE>> for MetadataValue<Ascii> {
509 #[inline]
510 fn from(h: MetadataKey<KeyVE>) -> MetadataValue<Ascii> {
511 MetadataValue {
512 inner: h.inner.into(),
513 phantom: PhantomData,
514 }
515 }
516}
517
518macro_rules! from_integers {
519 ($($name:ident: $t:ident => $max_len:expr),*) => {$(
520 impl From<$t> for MetadataValue<Ascii> {
521 fn from(num: $t) -> MetadataValue<Ascii> {
522 MetadataValue {
523 inner: HeaderValue::from(num),
524 phantom: PhantomData,
525 }
526 }
527 }
528
529 #[test]
530 fn $name() {
531 let n: $t = 55;
532 let val = AsciiMetadataValue::from(n);
533 assert_eq!(val, &n.to_string());
534
535 let n = $t::MAX;
536 let val = AsciiMetadataValue::from(n);
537 assert_eq!(val, &n.to_string());
538 }
539 )*};
540}
541
542from_integers! {
543 from_u16: u16 => 5,
547 from_i16: i16 => 6,
548 from_u32: u32 => 10,
549 from_i32: i32 => 11,
550 from_u64: u64 => 20,
551 from_i64: i64 => 20
552}
553
554#[cfg(target_pointer_width = "16")]
555from_integers! {
556 from_usize: usize => 5,
557 from_isize: isize => 6
558}
559
560#[cfg(target_pointer_width = "32")]
561from_integers! {
562 from_usize: usize => 10,
563 from_isize: isize => 11
564}
565
566#[cfg(target_pointer_width = "64")]
567from_integers! {
568 from_usize: usize => 20,
569 from_isize: isize => 20
570}
571
572#[cfg(test)]
573mod from_metadata_value_tests {
574 use super::*;
575 use crate::metadata::map::MetadataMap;
576
577 #[test]
578 fn it_can_insert_metadata_key_as_metadata_value() {
579 let mut map = MetadataMap::new();
580 map.insert(
581 "accept",
582 MetadataKey::<Ascii>::from_bytes(b"hello-world")
583 .unwrap()
584 .into(),
585 );
586
587 assert_eq!(
588 map.get("accept").unwrap(),
589 AsciiMetadataValue::try_from(b"hello-world").unwrap()
590 );
591 }
592}
593
594impl FromStr for MetadataValue<Ascii> {
595 type Err = InvalidMetadataValue;
596
597 #[inline]
598 fn from_str(s: &str) -> Result<MetadataValue<Ascii>, Self::Err> {
599 HeaderValue::from_str(s)
600 .map(|value| MetadataValue {
601 inner: value,
602 phantom: PhantomData,
603 })
604 .map_err(|_| InvalidMetadataValue::new())
605 }
606}
607
608impl<VE: ValueEncoding> From<MetadataValue<VE>> for Bytes {
609 #[inline]
610 fn from(value: MetadataValue<VE>) -> Bytes {
611 Bytes::copy_from_slice(value.inner.as_bytes())
612 }
613}
614
615impl<'a, VE: ValueEncoding> From<&'a MetadataValue<VE>> for MetadataValue<VE> {
616 #[inline]
617 fn from(t: &'a MetadataValue<VE>) -> Self {
618 t.clone()
619 }
620}
621
622impl ToStrError {
625 pub(crate) fn new() -> Self {
626 ToStrError { _priv: () }
627 }
628}
629
630impl fmt::Display for ToStrError {
631 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
632 f.write_str("failed to convert metadata to a str")
633 }
634}
635
636impl Error for ToStrError {}
637
638impl Hash for MetadataValue<Ascii> {
639 fn hash<H: Hasher>(&self, state: &mut H) {
640 self.inner.hash(state)
641 }
642}
643
644impl Hash for MetadataValue<Binary> {
645 fn hash<H: Hasher>(&self, state: &mut H) {
646 match self.to_bytes() {
647 Ok(b) => b.hash(state),
648 Err(e) => e.hash(state),
649 }
650 }
651}
652
653impl<VE: ValueEncoding> PartialEq for MetadataValue<VE> {
656 #[inline]
657 fn eq(&self, other: &MetadataValue<VE>) -> bool {
658 VE::values_equal(&self.inner, &other.inner)
663 }
664}
665
666impl<VE: ValueEncoding> Eq for MetadataValue<VE> {}
667
668impl<VE: ValueEncoding> PartialOrd for MetadataValue<VE> {
669 #[inline]
670 fn partial_cmp(&self, other: &MetadataValue<VE>) -> Option<cmp::Ordering> {
671 Some(self.cmp(other))
672 }
673}
674
675impl<VE: ValueEncoding> Ord for MetadataValue<VE> {
676 #[inline]
677 fn cmp(&self, other: &Self) -> cmp::Ordering {
678 self.inner.cmp(&other.inner)
679 }
680}
681
682impl<VE: ValueEncoding> PartialEq<str> for MetadataValue<VE> {
683 #[inline]
684 fn eq(&self, other: &str) -> bool {
685 VE::equals(&self.inner, other.as_bytes())
686 }
687}
688
689impl<VE: ValueEncoding> PartialEq<[u8]> for MetadataValue<VE> {
690 #[inline]
691 fn eq(&self, other: &[u8]) -> bool {
692 VE::equals(&self.inner, other)
693 }
694}
695
696impl<VE: ValueEncoding> PartialOrd<str> for MetadataValue<VE> {
697 #[inline]
698 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
699 self.inner.partial_cmp(other.as_bytes())
700 }
701}
702
703impl<VE: ValueEncoding> PartialOrd<[u8]> for MetadataValue<VE> {
704 #[inline]
705 fn partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering> {
706 self.inner.partial_cmp(other)
707 }
708}
709
710impl<VE: ValueEncoding> PartialEq<MetadataValue<VE>> for str {
711 #[inline]
712 fn eq(&self, other: &MetadataValue<VE>) -> bool {
713 *other == *self
714 }
715}
716
717impl<VE: ValueEncoding> PartialEq<MetadataValue<VE>> for [u8] {
718 #[inline]
719 fn eq(&self, other: &MetadataValue<VE>) -> bool {
720 *other == *self
721 }
722}
723
724impl<VE: ValueEncoding> PartialOrd<MetadataValue<VE>> for str {
725 #[inline]
726 fn partial_cmp(&self, other: &MetadataValue<VE>) -> Option<cmp::Ordering> {
727 self.as_bytes().partial_cmp(other.inner.as_bytes())
728 }
729}
730
731impl<VE: ValueEncoding> PartialOrd<MetadataValue<VE>> for [u8] {
732 #[inline]
733 fn partial_cmp(&self, other: &MetadataValue<VE>) -> Option<cmp::Ordering> {
734 self.partial_cmp(other.inner.as_bytes())
735 }
736}
737
738impl<VE: ValueEncoding> PartialEq<String> for MetadataValue<VE> {
739 #[inline]
740 fn eq(&self, other: &String) -> bool {
741 *self == other[..]
742 }
743}
744
745impl<VE: ValueEncoding> PartialOrd<String> for MetadataValue<VE> {
746 #[inline]
747 fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
748 self.inner.partial_cmp(other.as_bytes())
749 }
750}
751
752impl<VE: ValueEncoding> PartialEq<MetadataValue<VE>> for String {
753 #[inline]
754 fn eq(&self, other: &MetadataValue<VE>) -> bool {
755 *other == *self
756 }
757}
758
759impl<VE: ValueEncoding> PartialOrd<MetadataValue<VE>> for String {
760 #[inline]
761 fn partial_cmp(&self, other: &MetadataValue<VE>) -> Option<cmp::Ordering> {
762 self.as_bytes().partial_cmp(other.inner.as_bytes())
763 }
764}
765
766impl<VE: ValueEncoding> PartialEq<MetadataValue<VE>> for &MetadataValue<VE> {
767 #[inline]
768 fn eq(&self, other: &MetadataValue<VE>) -> bool {
769 **self == *other
770 }
771}
772
773impl<VE: ValueEncoding> PartialOrd<MetadataValue<VE>> for &MetadataValue<VE> {
774 #[inline]
775 fn partial_cmp(&self, other: &MetadataValue<VE>) -> Option<cmp::Ordering> {
776 (**self).partial_cmp(other)
777 }
778}
779
780impl<'a, VE: ValueEncoding, T: ?Sized> PartialEq<&'a T> for MetadataValue<VE>
781where
782 MetadataValue<VE>: PartialEq<T>,
783{
784 #[inline]
785 fn eq(&self, other: &&'a T) -> bool {
786 *self == **other
787 }
788}
789
790impl<'a, VE: ValueEncoding, T: ?Sized> PartialOrd<&'a T> for MetadataValue<VE>
791where
792 MetadataValue<VE>: PartialOrd<T>,
793{
794 #[inline]
795 fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
796 self.partial_cmp(*other)
797 }
798}
799
800impl<VE: ValueEncoding> PartialEq<MetadataValue<VE>> for &str {
801 #[inline]
802 fn eq(&self, other: &MetadataValue<VE>) -> bool {
803 *other == *self
804 }
805}
806
807impl<VE: ValueEncoding> PartialOrd<MetadataValue<VE>> for &str {
808 #[inline]
809 fn partial_cmp(&self, other: &MetadataValue<VE>) -> Option<cmp::Ordering> {
810 self.as_bytes().partial_cmp(other.inner.as_bytes())
811 }
812}
813
814#[test]
815fn test_debug() {
816 let cases = &[
817 ("hello", "\"hello\""),
818 ("hello \"world\"", "\"hello \\\"world\\\"\""),
819 ("\u{7FFF}hello", "\"\\xe7\\xbf\\xbfhello\""),
820 ];
821
822 for &(value, expected) in cases {
823 let val = AsciiMetadataValue::try_from(value.as_bytes()).unwrap();
824 let actual = format!("{val:?}");
825 assert_eq!(expected, actual);
826 }
827
828 let mut sensitive = AsciiMetadataValue::from_static("password");
829 sensitive.set_sensitive(true);
830 assert_eq!("Sensitive", format!("{sensitive:?}"));
831}
832
833#[test]
834fn test_is_empty() {
835 fn from_str<VE: ValueEncoding>(s: &str) -> MetadataValue<VE> {
836 MetadataValue::<VE>::unchecked_from_header_value(s.parse().unwrap())
837 }
838
839 assert!(from_str::<Ascii>("").is_empty());
840 assert!(from_str::<Binary>("").is_empty());
841 assert!(!from_str::<Ascii>("a").is_empty());
842 assert!(!from_str::<Binary>("a").is_empty());
843 assert!(!from_str::<Ascii>("=").is_empty());
844 assert!(from_str::<Binary>("=").is_empty());
845 assert!(!from_str::<Ascii>("===").is_empty());
846 assert!(from_str::<Binary>("===").is_empty());
847 assert!(!from_str::<Ascii>("=====").is_empty());
848 assert!(from_str::<Binary>("=====").is_empty());
849}
850
851#[test]
852fn test_from_shared_base64_encodes() {
853 let value = BinaryMetadataValue::try_from(Bytes::from_static(b"Hello")).unwrap();
854 assert_eq!(value.as_encoded_bytes(), b"SGVsbG8");
855}
856
857#[test]
858fn test_value_eq_value() {
859 type Bmv = BinaryMetadataValue;
860 type Amv = AsciiMetadataValue;
861
862 assert_eq!(Amv::from_static("abc"), Amv::from_static("abc"));
863 assert_ne!(Amv::from_static("abc"), Amv::from_static("ABC"));
864
865 assert_eq!(Bmv::from_bytes(b"abc"), Bmv::from_bytes(b"abc"));
866 assert_ne!(Bmv::from_bytes(b"abc"), Bmv::from_bytes(b"ABC"));
867
868 assert_eq!(
870 Bmv::from_static("SGVsbG8hIQ=="),
871 Bmv::from_static("SGVsbG8hIQ")
872 );
873 unsafe {
875 assert_eq!(
876 Bmv::from_shared_unchecked(Bytes::from_static(b"..{}")),
877 Bmv::from_shared_unchecked(Bytes::from_static(b"{}.."))
878 );
879 }
880}
881
882#[test]
883fn test_value_eq_str() {
884 type Bmv = BinaryMetadataValue;
885 type Amv = AsciiMetadataValue;
886
887 assert_eq!(Amv::from_static("abc"), "abc");
888 assert_ne!(Amv::from_static("abc"), "ABC");
889 assert_eq!("abc", Amv::from_static("abc"));
890 assert_ne!("ABC", Amv::from_static("abc"));
891
892 assert_eq!(Bmv::from_bytes(b"abc"), "abc");
893 assert_ne!(Bmv::from_bytes(b"abc"), "ABC");
894 assert_eq!("abc", Bmv::from_bytes(b"abc"));
895 assert_ne!("ABC", Bmv::from_bytes(b"abc"));
896
897 assert_eq!(Bmv::from_static("SGVsbG8hIQ=="), "Hello!!");
899 assert_eq!("Hello!!", Bmv::from_static("SGVsbG8hIQ=="));
900}
901
902#[test]
903fn test_value_eq_bytes() {
904 type Bmv = BinaryMetadataValue;
905 type Amv = AsciiMetadataValue;
906
907 assert_eq!(Amv::from_static("abc"), "abc".as_bytes());
908 assert_ne!(Amv::from_static("abc"), "ABC".as_bytes());
909 assert_eq!(*"abc".as_bytes(), Amv::from_static("abc"));
910 assert_ne!(*"ABC".as_bytes(), Amv::from_static("abc"));
911
912 assert_eq!(*"abc".as_bytes(), Bmv::from_bytes(b"abc"));
913 assert_ne!(*"ABC".as_bytes(), Bmv::from_bytes(b"abc"));
914
915 assert_eq!(Bmv::from_static("SGVsbG8hIQ=="), "Hello!!".as_bytes());
917 assert_eq!(*"Hello!!".as_bytes(), Bmv::from_static("SGVsbG8hIQ=="));
918}
919
920#[test]
921fn test_ascii_value_hash() {
922 use std::collections::hash_map::DefaultHasher;
923 type Amv = AsciiMetadataValue;
924
925 fn hash(value: Amv) -> u64 {
926 let mut hasher = DefaultHasher::new();
927 value.hash(&mut hasher);
928 hasher.finish()
929 }
930
931 let value1 = Amv::from_static("abc");
932 let value2 = Amv::from_static("abc");
933 assert_eq!(value1, value2);
934 assert_eq!(hash(value1), hash(value2));
935
936 let value1 = Amv::from_static("abc");
937 let value2 = Amv::from_static("xyz");
938
939 assert_ne!(value1, value2);
940 assert_ne!(hash(value1), hash(value2));
941}
942
943#[test]
944fn test_valid_binary_value_hash() {
945 use std::collections::hash_map::DefaultHasher;
946 type Bmv = BinaryMetadataValue;
947
948 fn hash(value: Bmv) -> u64 {
949 let mut hasher = DefaultHasher::new();
950 value.hash(&mut hasher);
951 hasher.finish()
952 }
953
954 let value1 = Bmv::from_bytes(b"abc");
955 let value2 = Bmv::from_bytes(b"abc");
956 assert_eq!(value1, value2);
957 assert_eq!(hash(value1), hash(value2));
958
959 let value1 = Bmv::from_bytes(b"abc");
960 let value2 = Bmv::from_bytes(b"xyz");
961 assert_ne!(value1, value2);
962 assert_ne!(hash(value1), hash(value2));
963}
964
965#[test]
966fn test_invalid_binary_value_hash() {
967 use std::collections::hash_map::DefaultHasher;
968 type Bmv = BinaryMetadataValue;
969
970 fn hash(value: Bmv) -> u64 {
971 let mut hasher = DefaultHasher::new();
972 value.hash(&mut hasher);
973 hasher.finish()
974 }
975
976 unsafe {
977 let value1 = Bmv::from_shared_unchecked(Bytes::from_static(b"..{}"));
978 let value2 = Bmv::from_shared_unchecked(Bytes::from_static(b"{}.."));
979 assert_eq!(value1, value2);
980 assert_eq!(hash(value1), hash(value2));
981 }
982
983 unsafe {
984 let valid = Bmv::from_bytes(b"abc");
985 let invalid = Bmv::from_shared_unchecked(Bytes::from_static(b"{}.."));
986 assert_ne!(valid, invalid);
987 assert_ne!(hash(valid), hash(invalid));
988 }
989}