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)]
12pub enum RawId {
13 Normal(RawIdNormal),
14 Backfilled(RawIdBackfilled),
15}
16
17type RawIdNormal = [u8; RawId::NORMAL_LEN];
18type RawIdBackfilled = [u8; RawId::BACKFILLED_LEN];
19
20struct RawIdVisitor;
21
22const INT_LEN: usize = size_of::<ShortId>();
23
24impl RawId {
25 const BACKFILLED_LEN: usize = size_of::<ShortRoomId>() + INT_LEN + size_of::<i64>();
26 const MAX_LEN: usize = Self::BACKFILLED_LEN;
27 const NORMAL_LEN: usize = size_of::<ShortRoomId>() + size_of::<u64>();
28
29 #[inline]
30 #[must_use]
31 pub fn is_room_eq(self, other: Self) -> bool { self.shortroomid() == other.shortroomid() }
32
33 #[inline]
34 #[must_use]
35 pub fn pdu_count(self) -> Count {
36 let id: Id = self.into();
37 id.count
38 }
39
40 #[inline]
41 #[must_use]
42 pub fn shortroomid(self) -> [u8; INT_LEN] {
43 match self {
44 | Self::Normal(raw) => raw[0..INT_LEN]
45 .try_into()
46 .expect("normal raw shortroomid array from slice"),
47 | Self::Backfilled(raw) => raw[0..INT_LEN]
48 .try_into()
49 .expect("backfilled raw shortroomid array from slice"),
50 }
51 }
52
53 #[inline]
54 #[must_use]
55 pub fn count(self) -> [u8; INT_LEN] {
56 match self {
57 | Self::Normal(raw) => raw[INT_LEN..INT_LEN * 2]
58 .try_into()
59 .expect("normal raw indice array from slice"),
60 | Self::Backfilled(raw) => raw[INT_LEN * 2..INT_LEN * 3]
61 .try_into()
62 .expect("backfilled raw indice array from slice"),
63 }
64 }
65
66 #[inline]
67 #[must_use]
68 pub fn as_bytes(&self) -> &[u8] {
69 match self {
70 | Self::Normal(raw) => raw,
71 | Self::Backfilled(raw) => raw,
72 }
73 }
74}
75
76impl fmt::Debug for RawId {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 let id: Id = (*self).into();
79 write!(f, "{id:?}")
80 }
81}
82
83impl<'de> Deserialize<'de> for RawId {
84 #[inline]
85 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
86 d.deserialize_bytes(RawIdVisitor)
87 }
88}
89
90impl serde::de::Visitor<'_> for RawIdVisitor {
91 type Value = RawId;
92
93 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 f.write_str("RawId byte array")
95 }
96
97 #[inline]
98 fn visit_bytes<E>(self, buf: &[u8]) -> Result<RawId, E> { Ok(RawId::from(buf)) }
99}
100
101impl From<Id> for RawId {
102 #[inline]
103 fn from(id: Id) -> Self {
104 const MAX_LEN: usize = RawId::MAX_LEN;
105 type RawVec = ArrayVec<u8, MAX_LEN>;
106
107 let mut vec = RawVec::new();
108 vec.extend(id.shortroomid.to_be_bytes());
109 id.count.debug_assert_valid();
110 match id.count {
111 | Count::Normal(count) => {
112 vec.extend(count.to_be_bytes());
113 Self::Normal(
114 vec.as_ref()
115 .try_into()
116 .expect("RawVec into RawId::Normal"),
117 )
118 },
119 | Count::Backfilled(count) => {
120 vec.extend(0_u64.to_be_bytes());
121 vec.extend(count.to_be_bytes());
122 Self::Backfilled(
123 vec.as_ref()
124 .try_into()
125 .expect("RawVec into RawId::Backfilled"),
126 )
127 },
128 }
129 }
130}
131
132impl From<&[u8]> for RawId {
133 #[inline]
134 fn from(id: &[u8]) -> Self {
135 match id.len() {
136 | Self::NORMAL_LEN => Self::Normal(
137 id[0..Self::NORMAL_LEN]
138 .try_into()
139 .expect("normal RawId from [u8]"),
140 ),
141 | Self::BACKFILLED_LEN => Self::Backfilled(
142 id[0..Self::BACKFILLED_LEN]
143 .try_into()
144 .expect("backfilled RawId from [u8]"),
145 ),
146 | _ => unimplemented!("unrecognized RawId length"),
147 }
148 }
149}
150
151impl From<&[u8; Self::NORMAL_LEN]> for RawId {
152 #[inline]
153 fn from(id: &[u8; Self::NORMAL_LEN]) -> Self { Self::Normal(*id) }
154}
155
156impl From<&[u8; Self::BACKFILLED_LEN]> for RawId {
157 #[inline]
158 fn from(id: &[u8; Self::BACKFILLED_LEN]) -> Self { Self::Backfilled(*id) }
159}
160
161impl AsRef<[u8]> for RawId {
162 #[inline]
163 fn as_ref(&self) -> &[u8] { self.as_bytes() }
164}