qudit_core/utils/
storage.rs1pub trait CompactStorage: Copy + 'static {
6 type InlineType: Copy + Default + 'static;
8 const CONVERSION_INFALLIBLE: bool;
10
11 fn to_inline(value: Self) -> Result<Self::InlineType, Self>;
14 fn from_inline(value: Self::InlineType) -> Self;
17
18 fn to_inline_unchecked(value: Self) -> Self::InlineType;
24}
25
26impl CompactStorage for i8 {
28 type InlineType = i8;
29 const CONVERSION_INFALLIBLE: bool = true;
30
31 #[inline(always)]
32 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
33 Ok(value)
34 }
35
36 #[inline(always)]
37 fn from_inline(value: Self::InlineType) -> Self {
38 value
39 }
40
41 #[inline(always)]
42 fn to_inline_unchecked(value: Self) -> Self::InlineType {
43 value
44 }
45}
46
47impl CompactStorage for i16 {
48 type InlineType = i8;
49 const CONVERSION_INFALLIBLE: bool = false;
50
51 #[inline]
52 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
53 if value >= i8::MIN as i16 && value <= i8::MAX as i16 {
54 Ok(value as i8)
55 } else {
56 Err(value)
57 }
58 }
59
60 #[inline(always)]
61 fn from_inline(value: Self::InlineType) -> Self {
62 value as i16
63 }
64
65 #[inline(always)]
66 fn to_inline_unchecked(value: Self) -> Self::InlineType {
67 value as i8
68 }
69}
70
71impl CompactStorage for i32 {
72 type InlineType = i8;
73 const CONVERSION_INFALLIBLE: bool = false;
74
75 #[inline]
76 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
77 if value >= i8::MIN as i32 && value <= i8::MAX as i32 {
78 Ok(value as i8)
79 } else {
80 Err(value)
81 }
82 }
83 #[inline(always)]
84 fn from_inline(value: Self::InlineType) -> Self {
85 value as i32
86 }
87
88 #[inline(always)]
89 fn to_inline_unchecked(value: Self) -> Self::InlineType {
90 value as i8
91 }
92}
93
94impl CompactStorage for i64 {
95 type InlineType = i8;
96 const CONVERSION_INFALLIBLE: bool = false;
97
98 #[inline]
99 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
100 if value >= i8::MIN as i64 && value <= i8::MAX as i64 {
101 Ok(value as i8)
102 } else {
103 Err(value)
104 }
105 }
106
107 #[inline(always)]
108 fn from_inline(value: Self::InlineType) -> Self {
109 value as i64
110 }
111
112 #[inline(always)]
113 fn to_inline_unchecked(value: Self) -> Self::InlineType {
114 value as i8
115 }
116}
117
118impl CompactStorage for i128 {
119 type InlineType = i8;
120 const CONVERSION_INFALLIBLE: bool = false;
121
122 #[inline]
123 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
124 if value >= i8::MIN as i128 && value <= i8::MAX as i128 {
125 Ok(value as i8)
126 } else {
127 Err(value)
128 }
129 }
130
131 #[inline(always)]
132 fn from_inline(value: Self::InlineType) -> Self {
133 value as i128
134 }
135
136 #[inline(always)]
137 fn to_inline_unchecked(value: Self) -> Self::InlineType {
138 value as i8
139 }
140}
141
142impl CompactStorage for isize {
143 type InlineType = i8;
144 const CONVERSION_INFALLIBLE: bool = false;
145
146 #[inline]
147 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
148 if value >= i8::MIN as isize && value <= i8::MAX as isize {
149 Ok(value as i8)
150 } else {
151 Err(value)
152 }
153 }
154
155 #[inline(always)]
156 fn from_inline(value: Self::InlineType) -> Self {
157 value as isize
158 }
159
160 #[inline(always)]
161 fn to_inline_unchecked(value: Self) -> Self::InlineType {
162 value as i8
163 }
164}
165
166impl CompactStorage for u8 {
168 type InlineType = u8;
169 const CONVERSION_INFALLIBLE: bool = true;
170
171 #[inline(always)]
172 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
173 Ok(value)
174 }
175
176 #[inline(always)]
177 fn from_inline(value: Self::InlineType) -> Self {
178 value
179 }
180
181 #[inline(always)]
182 fn to_inline_unchecked(value: Self) -> Self::InlineType {
183 value
184 }
185}
186
187impl CompactStorage for u16 {
188 type InlineType = u8;
189 const CONVERSION_INFALLIBLE: bool = false;
190
191 #[inline]
192 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
193 if value <= u8::MAX as u16 {
194 Ok(value as u8)
195 } else {
196 Err(value)
197 }
198 }
199
200 #[inline(always)]
201 fn from_inline(value: Self::InlineType) -> Self {
202 value as u16
203 }
204
205 #[inline(always)]
206 fn to_inline_unchecked(value: Self) -> Self::InlineType {
207 value as u8
208 }
209}
210
211impl CompactStorage for u32 {
212 type InlineType = u8;
213 const CONVERSION_INFALLIBLE: bool = false;
214
215 #[inline]
216 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
217 if value <= u8::MAX as u32 {
218 Ok(value as u8)
219 } else {
220 Err(value)
221 }
222 }
223
224 #[inline(always)]
225 fn from_inline(value: Self::InlineType) -> Self {
226 value as u32
227 }
228
229 #[inline(always)]
230 fn to_inline_unchecked(value: Self) -> Self::InlineType {
231 value as u8
232 }
233}
234
235impl CompactStorage for u64 {
236 type InlineType = u8;
237 const CONVERSION_INFALLIBLE: bool = false;
238
239 #[inline]
240 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
241 if value <= u8::MAX as u64 {
242 Ok(value as u8)
243 } else {
244 Err(value)
245 }
246 }
247
248 #[inline(always)]
249 fn from_inline(value: Self::InlineType) -> Self {
250 value as u64
251 }
252
253 #[inline(always)]
254 fn to_inline_unchecked(value: Self) -> Self::InlineType {
255 value as u8
256 }
257}
258
259impl CompactStorage for u128 {
260 type InlineType = u8;
261 const CONVERSION_INFALLIBLE: bool = false;
262
263 #[inline]
264 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
265 if value <= u8::MAX as u128 {
266 Ok(value as u8)
267 } else {
268 Err(value)
269 }
270 }
271
272 #[inline(always)]
273 fn from_inline(value: Self::InlineType) -> Self {
274 value as u128
275 }
276
277 #[inline(always)]
278 fn to_inline_unchecked(value: Self) -> Self::InlineType {
279 value as u8
280 }
281}
282
283impl CompactStorage for usize {
284 type InlineType = u8;
285 const CONVERSION_INFALLIBLE: bool = false;
286
287 #[inline]
288 fn to_inline(value: Self) -> Result<Self::InlineType, Self> {
289 if value <= u8::MAX as usize {
290 Ok(value as u8)
291 } else {
292 Err(value)
293 }
294 }
295
296 #[inline(always)]
297 fn from_inline(value: Self::InlineType) -> Self {
298 value as usize
299 }
300
301 #[inline(always)]
302 fn to_inline_unchecked(value: Self) -> Self::InlineType {
303 value as u8
304 }
305}
306
307#[cfg(test)]
308mod tests {
309 use super::*;
310
311 #[test]
313 fn test_infallible_conversions() {
314 #![allow(clippy::assertions_on_constants)]
315 assert!(i8::CONVERSION_INFALLIBLE);
316 assert!(u8::CONVERSION_INFALLIBLE);
317 assert_eq!(i8::to_inline(42), Ok(42));
318 assert_eq!(u8::to_inline(42), Ok(42));
319 }
320
321 #[test]
323 fn test_signed_conversions() {
324 assert_eq!(i16::to_inline(42), Ok(42));
326 assert_eq!(i32::to_inline(-42), Ok(-42));
327 assert_eq!(i64::to_inline(127), Ok(127));
328 assert_eq!(i128::to_inline(-128), Ok(-128));
329
330 assert!(i16::to_inline(200).is_err());
332 assert!(i32::to_inline(1000).is_err());
333 assert!(i64::to_inline(i64::MAX).is_err());
334 assert!(i128::to_inline(i128::MAX).is_err());
335 }
336
337 #[test]
339 fn test_unsigned_conversions() {
340 assert_eq!(u16::to_inline(42), Ok(42));
342 assert_eq!(u32::to_inline(255), Ok(255));
343 assert_eq!(u64::to_inline(100), Ok(100));
344 assert_eq!(u128::to_inline(200), Ok(200));
345
346 assert!(u16::to_inline(300).is_err());
348 assert!(u32::to_inline(1000).is_err());
349 assert!(u64::to_inline(u64::MAX).is_err());
350 assert!(u128::to_inline(u128::MAX).is_err());
351 }
352
353 #[test]
355 fn test_round_trip() {
356 assert_eq!(i128::from_inline(42), 42i128);
357 assert_eq!(u128::from_inline(255), 255u128);
358 }
359}