1use super::util::encode_u32;
17use core::convert::From;
18use core::ops::Deref;
19
20#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, Ord, PartialOrd)]
22pub struct ETag {
23 len: u8,
24 bytes: [u8; 8],
25}
26
27impl ETag {
28 pub const MAX_LEN: usize = 8;
30
31 pub const EMPTY: ETag = ETag {
33 len: 0u8,
34 bytes: [0; 8],
35 };
36
37 pub fn new(x: &[u8]) -> ETag {
39 ETag::from(x)
40 }
41
42 pub fn len(&self) -> usize {
44 self.len as usize
45 }
46
47 pub fn is_empty(&self) -> bool {
49 self.len == 0
50 }
51
52 pub fn as_bytes(&self) -> &[u8] {
54 &self.bytes[..self.len as usize]
55 }
56}
57
58impl std::fmt::Display for ETag {
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 for b in self.as_bytes() {
61 write!(f, "{:02X}", b)?;
62 }
63 Ok(())
64 }
65}
66
67impl Default for ETag {
68 fn default() -> Self {
69 ETag::EMPTY
70 }
71}
72
73impl Deref for ETag {
74 type Target = [u8];
75
76 fn deref(&self) -> &Self::Target {
77 self.as_bytes()
78 }
79}
80
81impl core::cmp::PartialEq<[u8]> for ETag {
82 fn eq(&self, other: &[u8]) -> bool {
83 self.as_bytes() == other
84 }
85}
86
87impl core::convert::From<u32> for ETag {
88 fn from(x: u32) -> Self {
89 let mut bytes = [0u8; 8];
90 let len = encode_u32(x, &mut bytes).len();
91 ETag {
92 len: len as u8,
93 bytes,
94 }
95 }
96}
97
98impl core::convert::From<i32> for ETag {
99 fn from(x: i32) -> Self {
100 core::convert::Into::into(x as u32)
101 }
102}
103
104impl core::convert::From<u16> for ETag {
105 fn from(x: u16) -> Self {
106 core::convert::Into::into(x as u32)
107 }
108}
109
110impl core::convert::From<&[u8]> for ETag {
111 fn from(x: &[u8]) -> Self {
113 let mut bytes = [0u8; 8];
114 let len = x.len();
115 bytes[..len].copy_from_slice(x);
116 ETag {
117 len: len as u8,
118 bytes,
119 }
120 }
121}