tuwunel_core/matrix/pdu/
raw_id.rs1use std::fmt;
2
3use arrayvec::ArrayVec;
4use serde::{Deserialize, Deserializer};
5
6use super::{
7 super::{ShortId, ShortRoomId},
8 Count, Id,
9};
10
11#[derive(Clone, Copy, Eq, Hash, PartialEq)]
16pub enum RawId {
17 Normal(RawIdNormal),
22
23 Backfilled(RawIdBackfilled),
28}
29
30type RawIdNormal = [u8; RawId::NORMAL_LEN];
31type RawIdBackfilled = [u8; RawId::BACKFILLED_LEN];
32
33struct RawIdVisitor;
34
35const INT_LEN: usize = size_of::<ShortId>();
36
37impl RawId {
38 const BACKFILLED_LEN: usize = size_of::<ShortRoomId>() + INT_LEN + size_of::<i64>();
39 const MAX_LEN: usize = Self::BACKFILLED_LEN;
40 const NORMAL_LEN: usize = size_of::<ShortRoomId>() + size_of::<u64>();
41
42 #[inline]
47 #[must_use]
48 pub fn is_room_eq(self, other: Self) -> bool { self.shortroomid() == other.shortroomid() }
49
50 #[inline]
55 #[must_use]
56 pub fn pdu_count(self) -> Count {
57 let id: Id = self.into();
58 id.count
59 }
60
61 #[inline]
66 #[must_use]
67 pub fn shortroomid(self) -> [u8; INT_LEN] {
68 match self {
69 | Self::Normal(raw) => raw[0..INT_LEN]
70 .try_into()
71 .expect("normal raw shortroomid array from slice"),
72 | Self::Backfilled(raw) => raw[0..INT_LEN]
73 .try_into()
74 .expect("backfilled raw shortroomid array from slice"),
75 }
76 }
77
78 #[inline]
83 #[must_use]
84 pub fn count(self) -> [u8; INT_LEN] {
85 match self {
86 | Self::Normal(raw) => raw[INT_LEN..INT_LEN * 2]
87 .try_into()
88 .expect("normal raw indice array from slice"),
89 | Self::Backfilled(raw) => raw[INT_LEN * 2..INT_LEN * 3]
90 .try_into()
91 .expect("backfilled raw indice array from slice"),
92 }
93 }
94
95 #[inline]
100 #[must_use]
101 pub fn as_bytes(&self) -> &[u8] {
102 match self {
103 | Self::Normal(raw) => raw,
104 | Self::Backfilled(raw) => raw,
105 }
106 }
107}
108
109impl fmt::Debug for RawId {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 let id: Id = (*self).into();
112 write!(f, "{id:?}")
113 }
114}
115
116impl<'de> Deserialize<'de> for RawId {
117 #[inline]
118 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
119 d.deserialize_bytes(RawIdVisitor)
120 }
121}
122
123impl serde::de::Visitor<'_> for RawIdVisitor {
124 type Value = RawId;
125
126 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 f.write_str("RawId byte array")
128 }
129
130 #[inline]
131 fn visit_bytes<E>(self, buf: &[u8]) -> Result<RawId, E> { Ok(RawId::from(buf)) }
132}
133
134impl From<Id> for RawId {
135 #[inline]
136 fn from(id: Id) -> Self {
137 const MAX_LEN: usize = RawId::MAX_LEN;
138 type RawVec = ArrayVec<u8, MAX_LEN>;
139
140 let mut vec = RawVec::new();
141 vec.extend(id.shortroomid.to_be_bytes());
142 id.count.debug_assert_valid();
143 match id.count {
144 | Count::Normal(count) => {
145 vec.extend(count.to_be_bytes());
146 Self::Normal(
147 vec.as_ref()
148 .try_into()
149 .expect("RawVec into RawId::Normal"),
150 )
151 },
152 | Count::Backfilled(count) => {
153 vec.extend(0_u64.to_be_bytes());
154 vec.extend(count.to_be_bytes());
155 Self::Backfilled(
156 vec.as_ref()
157 .try_into()
158 .expect("RawVec into RawId::Backfilled"),
159 )
160 },
161 }
162 }
163}
164
165impl From<&[u8]> for RawId {
166 #[inline]
167 fn from(id: &[u8]) -> Self {
168 match id.len() {
169 | Self::NORMAL_LEN => Self::Normal(
170 id[0..Self::NORMAL_LEN]
171 .try_into()
172 .expect("normal RawId from [u8]"),
173 ),
174 | Self::BACKFILLED_LEN => Self::Backfilled(
175 id[0..Self::BACKFILLED_LEN]
176 .try_into()
177 .expect("backfilled RawId from [u8]"),
178 ),
179 | _ => unimplemented!("unrecognized RawId length"),
180 }
181 }
182}
183
184impl From<&[u8; Self::NORMAL_LEN]> for RawId {
185 #[inline]
186 fn from(id: &[u8; Self::NORMAL_LEN]) -> Self { Self::Normal(*id) }
187}
188
189impl From<&[u8; Self::BACKFILLED_LEN]> for RawId {
190 #[inline]
191 fn from(id: &[u8; Self::BACKFILLED_LEN]) -> Self { Self::Backfilled(*id) }
192}
193
194impl AsRef<[u8]> for RawId {
195 #[inline]
196 fn as_ref(&self) -> &[u8] { self.as_bytes() }
197}