tacacs_plus_protocol/authentication/
data.rs1use core::fmt;
2
3#[derive(Debug, Clone, PartialEq, Eq, Ord, Hash)]
4enum PacketDataInner<'data> {
5 Borrowed(&'data [u8]),
6
7 #[cfg(feature = "std")]
8 Owned(std::vec::Vec<u8>),
9}
10
11impl PartialOrd for PacketDataInner<'_> {
12 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
13 Some(self.as_ref().cmp(other.as_ref()))
14 }
15}
16
17#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct PacketData<'data>(PacketDataInner<'data>);
20
21impl PacketData<'_> {
22 pub fn new() -> Self {
24 Default::default()
25 }
26}
27
28impl Default for PacketData<'_> {
29 fn default() -> Self {
30 Self(PacketDataInner::Borrowed(&[]))
31 }
32}
33
34#[derive(Debug, PartialEq, Eq)]
36pub struct DataTooLong(pub(super) ());
37
38impl fmt::Display for DataTooLong {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(
41 f,
42 "data was too long for the data field of an authentication start packet"
43 )
44 }
45}
46
47impl<'data> TryFrom<&'data [u8]> for PacketData<'data> {
48 type Error = DataTooLong;
49
50 fn try_from(value: &'data [u8]) -> Result<Self, Self::Error> {
51 if u8::try_from(value.len()).is_ok() {
53 Ok(Self(PacketDataInner::Borrowed(value)))
54 } else {
55 Err(DataTooLong(()))
56 }
57 }
58}
59
60#[cfg(feature = "std")]
61impl TryFrom<std::vec::Vec<u8>> for PacketData<'_> {
62 type Error = DataTooLong;
63
64 fn try_from(value: std::vec::Vec<u8>) -> Result<Self, Self::Error> {
65 if u8::try_from(value.len()).is_ok() {
67 Ok(Self(PacketDataInner::Owned(value)))
68 } else {
69 Err(DataTooLong(()))
70 }
71 }
72}
73
74impl AsRef<[u8]> for PacketDataInner<'_> {
75 fn as_ref(&self) -> &[u8] {
76 match self {
77 Self::Borrowed(data) => data,
78
79 #[cfg(feature = "std")]
80 Self::Owned(vec) => vec,
81 }
82 }
83}
84
85impl PacketData<'_> {
86 #[allow(clippy::len_without_is_empty)]
89 pub fn len(&self) -> u8 {
90 u8::try_from(self.as_bytes().len()).unwrap()
92 }
93
94 pub fn as_bytes(&self) -> &[u8] {
96 self.0.as_ref()
97 }
98}