1pub mod prelude;
16pub mod typestate;
17pub use crate::typestate::{
18 CheckComplete, CheckOk, CompleteState, InfallibleRead, InfallibleWrite, IntoWriter,
19 IsComplete, IsOk, Ok, OkState, State, UncheckedState,
20};
21
22pub trait SafeCmp<Rhs> {
24 fn safe_eq(&self, other: Rhs) -> bool;
25 fn safe_less(&self, other: Rhs) -> bool;
26}
27
28impl SafeCmp<u64> for u64 {
29 fn safe_eq(&self, other: u64) -> bool {
30 *self == other
31 }
32 fn safe_less(&self, other: u64) -> bool {
33 *self < other
34 }
35}
36
37impl SafeCmp<i64> for i64 {
38 fn safe_eq(&self, other: i64) -> bool {
39 *self == other
40 }
41 fn safe_less(&self, other: i64) -> bool {
42 *self < other
43 }
44}
45
46impl SafeCmp<u64> for i64 {
47 fn safe_eq(&self, other: u64) -> bool {
48 *self >= 0 && (*self as u64) == other
49 }
50 fn safe_less(&self, other: u64) -> bool {
51 *self < 0 || (*self as u64) < other
52 }
53}
54
55impl SafeCmp<i64> for u64 {
56 fn safe_eq(&self, other: i64) -> bool {
57 other >= 0 && *self == (other as u64)
58 }
59 fn safe_less(&self, other: i64) -> bool {
60 other >= 0 && *self < (other as u64)
61 }
62}
63
64impl SafeCmp<bool> for bool {
65 fn safe_eq(&self, other: bool) -> bool {
66 *self == other
67 }
68 fn safe_less(&self, other: bool) -> bool {
69 !*self && other
70 }
71}
72
73#[derive(Clone, Copy, Debug, PartialEq, Eq)]
74pub enum Error<T = ()> {
75 OutOfBounds,
76 UnknownEnum(T),
77}
78
79impl<T> Error<T> {
80 pub fn map_type<U>(self) -> Error<U> {
81 match self {
82 Error::OutOfBounds => Error::OutOfBounds,
83 Error::UnknownEnum(_) => unreachable!("Cannot map UnknownEnum across unmodified types"),
84 }
85 }
86}
87
88pub trait Storage {
89 type Sliced<'a>: Storage where Self: 'a;
90 fn slice(&self, offset: usize, length: usize) -> Self::Sliced<'_>;
91 fn try_read_byte(&self, offset: usize) -> Result<u8, Error>;
92 fn len(&self) -> usize;
93 fn is_empty(&self) -> bool {
94 self.len() == 0
95 }
96}
97
98pub trait MutStorage: Storage {
99 type SlicedMut<'a>: MutStorage where Self: 'a;
100 fn slice_mut(&mut self, offset: usize, length: usize) -> Self::SlicedMut<'_>;
101 fn try_write_byte(&mut self, offset: usize, val: u8) -> Result<(), Error>;
102}
103
104impl<T: ?Sized + AsRef<[u8]>> Storage for T {
105 type Sliced<'b> = &'b [u8] where Self: 'b;
106 fn slice(&self, offset: usize, length: usize) -> &[u8] {
107 let bytes = self.as_ref();
108 if offset >= bytes.len() {
109 &[]
110 } else {
111 let end = offset.saturating_add(length).min(bytes.len());
112 &bytes[offset..end]
113 }
114 }
115 fn try_read_byte(&self, offset: usize) -> Result<u8, Error> {
116 self.as_ref().get(offset).copied().ok_or(Error::OutOfBounds)
117 }
118 fn len(&self) -> usize {
119 self.as_ref().len()
120 }
121}
122
123impl<T: ?Sized + AsMut<[u8]> + AsRef<[u8]>> MutStorage for T {
124 type SlicedMut<'b> = &'b mut [u8] where Self: 'b;
125 fn slice_mut(&mut self, offset: usize, length: usize) -> &mut [u8] {
126 let bytes = self.as_mut();
127 if offset >= bytes.len() {
128 &mut []
129 } else {
130 let end = offset.saturating_add(length).min(bytes.len());
131 &mut bytes[offset..end]
132 }
133 }
134 fn try_write_byte(&mut self, offset: usize, val: u8) -> Result<(), Error> {
135 let b = self.as_mut().get_mut(offset).ok_or(Error::OutOfBounds)?;
136 *b = val;
137 Ok(())
138 }
139}
140
141pub trait ByteOrder {
142 fn shift(i: usize, size_in_bytes: usize) -> usize;
143}
144
145#[derive(Clone, Copy, Debug, PartialEq, Eq)]
146pub struct LittleEndian;
147impl ByteOrder for LittleEndian {
148 #[inline(always)]
149 fn shift(i: usize, _size_in_bytes: usize) -> usize {
150 i * 8
151 }
152}
153
154#[derive(Clone, Copy, Debug, PartialEq, Eq)]
155pub struct BigEndian;
156impl ByteOrder for BigEndian {
157 #[inline(always)]
158 fn shift(i: usize, size_in_bytes: usize) -> usize {
159 (size_in_bytes - 1 - i) * 8
160 }
161}
162
163#[derive(Clone, Copy, Debug, PartialEq, Eq)]
164pub struct Null;
165impl ByteOrder for Null {
166 #[inline(always)]
167 fn shift(_i: usize, _size_in_bytes: usize) -> usize {
168 0
169 }
170}
171
172pub trait DecodeFromStorage<E: ByteOrder>: Sized {
173 fn decode<S: Storage>(storage: &S, size_in_bytes: usize) -> Result<Self, Error>;
174}
175
176pub trait EncodeToStorage<E: ByteOrder>: Sized {
177 fn encode<S: MutStorage>(&self, storage: &mut S, size_in_bytes: usize) -> Result<(), Error>;
178}
179
180macro_rules! impl_decode_uint {
181 ($type:ty) => {
182 impl<E: ByteOrder> DecodeFromStorage<E> for $type {
183 fn decode<S: Storage>(storage: &S, size_in_bytes: usize) -> Result<Self, Error> {
184 let mut val: $type = 0;
185 for i in 0..size_in_bytes {
186 val |= (storage.try_read_byte(i)? as $type) << E::shift(i, size_in_bytes);
187 }
188 Ok(val)
189 }
190 }
191 impl<E: ByteOrder> EncodeToStorage<E> for $type {
192 fn encode<S: MutStorage>(&self, storage: &mut S, size_in_bytes: usize) -> Result<(), Error> {
193 for i in 0..size_in_bytes {
194 storage.try_write_byte(i, ((*self) >> E::shift(i, size_in_bytes)) as u8)?;
195 }
196 Ok(())
197 }
198 }
199 };
200}
201impl_decode_uint!(u8);
202impl_decode_uint!(u16);
203impl_decode_uint!(u32);
204impl_decode_uint!(u64);
205
206pub trait SmallestUInt {
207 type T;
208 fn from_u64(val: u64) -> Self::T;
209}
210pub struct SizeSelector<const BITS: usize>;
211
212macro_rules! impl_smallest_uint {
213 ($type:ty, $($bits:expr),+) => {
214 $(
215 impl SmallestUInt for SizeSelector<$bits> {
216 type T = $type;
217 #[inline]
218 fn from_u64(val: u64) -> Self::T { val as $type }
219 }
220 )+
221 };
222}
223impl_smallest_uint!(u8, 1, 2, 3, 4, 5, 6, 7, 8);
224impl_smallest_uint!(u16, 9, 10, 11, 12, 13, 14, 15, 16);
225impl_smallest_uint!(
226 u32, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
227);
228impl_smallest_uint!(
229 u64, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48
230);
231impl_smallest_uint!(
232 u64, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
233);
234
235pub trait SmallestFlag {
236 type T;
237}
238
239impl<const BITS: usize> SmallestFlag for SizeSelector<BITS> {
240 type T = bool;
241}
242
243pub struct UInt<const BITS: usize, E: ByteOrder, S: Storage, ST: State = UncheckedState> {
244 storage: S,
245 _marker: core::marker::PhantomData<(E, ST)>,
246}
247
248impl<const BITS: usize, E: ByteOrder, S: Storage, ST: State> UInt<BITS, E, S, ST> {
249 pub fn new(storage: S) -> Self {
250 Self {
251 storage,
252 _marker: core::marker::PhantomData,
253 }
254 }
255}
256
257impl<const BITS: usize, E: ByteOrder, S: Storage + Clone, ST: State> Clone for UInt<BITS, E, S, ST> {
258 fn clone(&self) -> Self {
259 Self {
260 storage: self.storage.clone(),
261 _marker: core::marker::PhantomData,
262 }
263 }
264}
265
266impl<const BITS: usize, E: ByteOrder, S: Storage, ST: State> UInt<BITS, E, S, ST>
267where
268 SizeSelector<BITS>: SmallestUInt,
269 <SizeSelector<BITS> as SmallestUInt>::T: DecodeFromStorage<E>,
270{
271 pub fn try_read(&self) -> Result<<SizeSelector<BITS> as SmallestUInt>::T, Error> {
272 let size_in_bytes = (BITS + 7) / 8;
273 <<SizeSelector<BITS> as SmallestUInt>::T as DecodeFromStorage<E>>::decode(
274 &self.storage,
275 size_in_bytes,
276 )
277 }
278}
279
280impl<const BITS: usize, E: ByteOrder, S: MutStorage, ST: State> UInt<BITS, E, S, ST>
281where
282 SizeSelector<BITS>: SmallestUInt,
283 <SizeSelector<BITS> as SmallestUInt>::T: EncodeToStorage<E>,
284{
285 pub fn try_write(&mut self, val: <SizeSelector<BITS> as SmallestUInt>::T) -> Result<(), Error> {
286 let size_in_bytes = (BITS + 7) / 8;
287 val.encode(&mut self.storage, size_in_bytes)
288 }
289}
290
291impl<const BITS: usize, E: ByteOrder, S: Storage, ST: IsOk> InfallibleRead
292 for UInt<BITS, E, S, ST>
293where
294 SizeSelector<BITS>: SmallestUInt,
295 <SizeSelector<BITS> as SmallestUInt>::T: DecodeFromStorage<E>,
296{
297 type ReadValue = <SizeSelector<BITS> as SmallestUInt>::T;
298 fn read(&self) -> <SizeSelector<BITS> as SmallestUInt>::T {
299 self.try_read().expect("infallible read in ok state")
300 }
301}
302
303impl<const BITS: usize, E: ByteOrder, S: MutStorage, ST: IsComplete> InfallibleWrite
304 for UInt<BITS, E, S, ST>
305where
306 SizeSelector<BITS>: SmallestUInt,
307 <SizeSelector<BITS> as SmallestUInt>::T: EncodeToStorage<E>,
308{
309 type WriteValue = <SizeSelector<BITS> as SmallestUInt>::T;
310 type Output = UInt<BITS, E, S, ST::OnLayoutMutation>;
311 fn write(mut self, val: <SizeSelector<BITS> as SmallestUInt>::T) -> Self::Output {
312 self.try_write(val).expect("infallible write in complete state");
313 UInt {
314 storage: self.storage,
315 _marker: core::marker::PhantomData,
316 }
317 }
318}
319
320pub trait SmallestInt {
321 type T;
322 type U;
323 fn sign_extend(raw: Self::U, bits: usize) -> Self::T;
324 fn mask_to_unsigned(val: Self::T, bits: usize) -> Self::U;
325}
326
327macro_rules! impl_smallest_int {
328 ($type:ty, $utype:ty, $($bits:expr),+) => {
329 $(
330 impl SmallestInt for SizeSelector<$bits> {
331 type T = $type;
332 type U = $utype;
333 #[inline]
334 fn sign_extend(raw: Self::U, bits: usize) -> Self::T {
335 let shift_amount = (core::mem::size_of::<$type>() * 8) - bits;
336 let sign_extended = (raw as $type) << shift_amount;
337 sign_extended >> shift_amount
338 }
339 #[inline]
340 fn mask_to_unsigned(val: Self::T, bits: usize) -> Self::U {
341 let mask = if bits == core::mem::size_of::<$utype>() * 8 {
342 !0
343 } else {
344 (1 << bits) - 1
345 };
346 (val as Self::U) & mask
347 }
348 }
349 )+
350 };
351}
352
353impl_smallest_int!(i8, u8, 1, 2, 3, 4, 5, 6, 7, 8);
354impl_smallest_int!(i16, u16, 9, 10, 11, 12, 13, 14, 15, 16);
355impl_smallest_int!(
356 i32, u32, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
357);
358impl_smallest_int!(
359 i64, u64, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48
360);
361impl_smallest_int!(
362 i64, u64, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
363);
364
365pub struct Int<const BITS: usize, E: ByteOrder, S: Storage, ST: State = UncheckedState> {
366 storage: S,
367 _marker: core::marker::PhantomData<(E, ST)>,
368}
369
370impl<const BITS: usize, E: ByteOrder, S: Storage, ST: State> Int<BITS, E, S, ST> {
371 pub fn new(storage: S) -> Self {
372 Self {
373 storage,
374 _marker: core::marker::PhantomData,
375 }
376 }
377}
378
379impl<const BITS: usize, E: ByteOrder, S: Storage + Clone, ST: State> Clone for Int<BITS, E, S, ST> {
380 fn clone(&self) -> Self {
381 Self {
382 storage: self.storage.clone(),
383 _marker: core::marker::PhantomData,
384 }
385 }
386}
387
388impl<const BITS: usize, E: ByteOrder, S: Storage, ST: State> Int<BITS, E, S, ST>
389where
390 SizeSelector<BITS>: SmallestUInt + SmallestInt<U = <SizeSelector<BITS> as SmallestUInt>::T>,
391 <SizeSelector<BITS> as SmallestUInt>::T: DecodeFromStorage<E>,
392{
393 pub fn try_read(&self) -> Result<<SizeSelector<BITS> as SmallestInt>::T, Error> {
394 let size_in_bytes = (BITS + 7) / 8;
395 let slice = self.storage.slice(0, size_in_bytes);
396 let raw = UInt::<BITS, E, S::Sliced<'_>>::new(slice).try_read()?;
397 Ok(<SizeSelector<BITS> as SmallestInt>::sign_extend(raw, BITS))
398 }
399}
400
401impl<const BITS: usize, E: ByteOrder, S: MutStorage, ST: State> Int<BITS, E, S, ST>
402where
403 SizeSelector<BITS>: SmallestUInt + SmallestInt<U = <SizeSelector<BITS> as SmallestUInt>::T>,
404 <SizeSelector<BITS> as SmallestUInt>::T: EncodeToStorage<E>,
405{
406 pub fn try_write(&mut self, val: <SizeSelector<BITS> as SmallestInt>::T) -> Result<(), Error> {
407 let unsigned = <SizeSelector<BITS> as SmallestInt>::mask_to_unsigned(val, BITS);
408 let mut uint_view = UInt::<BITS, E, S::SlicedMut<'_>>::new(self.storage.slice_mut(0, (BITS + 7) / 8));
409 uint_view.try_write(unsigned)
410 }
411}
412
413impl<const BITS: usize, E: ByteOrder, S: Storage, ST: IsOk> InfallibleRead
414 for Int<BITS, E, S, ST>
415where
416 SizeSelector<BITS>: SmallestUInt + SmallestInt<U = <SizeSelector<BITS> as SmallestUInt>::T>,
417 <SizeSelector<BITS> as SmallestUInt>::T: DecodeFromStorage<E>,
418{
419 type ReadValue = <SizeSelector<BITS> as SmallestInt>::T;
420 fn read(&self) -> <SizeSelector<BITS> as SmallestInt>::T {
421 self.try_read().expect("infallible read in ok state")
422 }
423}
424
425impl<const BITS: usize, E: ByteOrder, S: MutStorage, ST: IsComplete> InfallibleWrite
426 for Int<BITS, E, S, ST>
427where
428 SizeSelector<BITS>: SmallestUInt + SmallestInt<U = <SizeSelector<BITS> as SmallestUInt>::T>,
429 <SizeSelector<BITS> as SmallestUInt>::T: EncodeToStorage<E>,
430{
431 type WriteValue = <SizeSelector<BITS> as SmallestInt>::T;
432 type Output = Int<BITS, E, S, ST::OnLayoutMutation>;
433 fn write(mut self, val: <SizeSelector<BITS> as SmallestInt>::T) -> Self::Output {
434 self.try_write(val).expect("infallible write in complete state");
435 Int {
436 storage: self.storage,
437 _marker: core::marker::PhantomData,
438 }
439 }
440}
441
442pub trait TryFromRaw<T> {
443 fn try_from_raw(val: T) -> Result<Self, Error<T>>
444 where
445 Self: Sized;
446}
447
448pub struct EnumView<T, Inner> {
449 pub inner: Inner,
450 _phantom: core::marker::PhantomData<T>,
451}
452
453impl<T, Inner> EnumView<T, Inner> {
454 pub fn new(inner: Inner) -> Self {
455 Self {
456 inner,
457 _phantom: core::marker::PhantomData,
458 }
459 }
460}
461
462pub struct EnumViewMut<T, Inner> {
463 pub inner: Inner,
464 _phantom: core::marker::PhantomData<T>,
465}
466
467impl<T, Inner> EnumViewMut<T, Inner> {
468 pub fn new(inner: Inner) -> Self {
469 Self {
470 inner,
471 _phantom: core::marker::PhantomData,
472 }
473 }
474}
475
476impl<T, Inner: Clone> Clone for EnumView<T, Inner> {
477 fn clone(&self) -> Self {
478 Self {
479 inner: self.inner.clone(),
480 _phantom: core::marker::PhantomData,
481 }
482 }
483}
484
485impl<T, Inner: Clone> Clone for EnumViewMut<T, Inner> {
486 fn clone(&self) -> Self {
487 Self {
488 inner: self.inner.clone(),
489 _phantom: core::marker::PhantomData,
490 }
491 }
492}
493
494pub trait View {
496 fn size_in_bytes(&self) -> Result<usize, Error>;
498}
499
500pub trait TryRead {
501 type ReadValue;
502 fn try_read(&self) -> Result<Self::ReadValue, Error>;
503}
504
505pub trait TryWrite {
506 type WriteValue;
507 fn try_write(&mut self, val: Self::WriteValue) -> Result<(), Error>;
508}
509
510impl<const BITS: usize, E: ByteOrder, S: Storage, ST: State> TryRead for UInt<BITS, E, S, ST>
511where
512 SizeSelector<BITS>: SmallestUInt,
513 <SizeSelector<BITS> as SmallestUInt>::T: DecodeFromStorage<E>,
514{
515 type ReadValue = <SizeSelector<BITS> as SmallestUInt>::T;
516 fn try_read(&self) -> Result<Self::ReadValue, Error> {
517 self.try_read()
518 }
519}
520
521impl<const BITS: usize, E: ByteOrder, S: MutStorage, ST: State> TryWrite for UInt<BITS, E, S, ST>
522where
523 SizeSelector<BITS>: SmallestUInt,
524 <SizeSelector<BITS> as SmallestUInt>::T: EncodeToStorage<E>,
525{
526 type WriteValue = <SizeSelector<BITS> as SmallestUInt>::T;
527 fn try_write(&mut self, val: Self::WriteValue) -> Result<(), Error> {
528 self.try_write(val)
529 }
530}
531
532impl<const BITS: usize, E: ByteOrder, S: Storage, ST: State> TryRead for Int<BITS, E, S, ST>
533where
534 SizeSelector<BITS>: SmallestUInt + SmallestInt<U = <SizeSelector<BITS> as SmallestUInt>::T>,
535 <SizeSelector<BITS> as SmallestUInt>::T: DecodeFromStorage<E>,
536{
537 type ReadValue = <SizeSelector<BITS> as SmallestInt>::T;
538 fn try_read(&self) -> Result<Self::ReadValue, Error> {
539 self.try_read()
540 }
541}
542
543impl<const BITS: usize, E: ByteOrder, S: MutStorage, ST: State> TryWrite for Int<BITS, E, S, ST>
544where
545 SizeSelector<BITS>: SmallestUInt + SmallestInt<U = <SizeSelector<BITS> as SmallestUInt>::T>,
546 <SizeSelector<BITS> as SmallestUInt>::T: EncodeToStorage<E>,
547{
548 type WriteValue = <SizeSelector<BITS> as SmallestInt>::T;
549 fn try_write(&mut self, val: Self::WriteValue) -> Result<(), Error> {
550 self.try_write(val)
551 }
552}
553
554impl<T, Inner> EnumView<T, Inner>
555where
556 Inner: TryRead,
557 T: TryFromRaw<Inner::ReadValue>,
558{
559 pub fn try_read(&self) -> Result<T, Error<Inner::ReadValue>> {
560 let raw = self.inner.try_read().map_err(|e| e.map_type())?;
561 T::try_from_raw(raw)
562 }
563}
564
565impl<T, Inner> InfallibleRead for EnumView<T, Inner>
566where
567 Inner: InfallibleRead,
568 T: TryFromRaw<Inner::ReadValue>,
569{
570 type ReadValue = Result<T, Error<Inner::ReadValue>>;
571 fn read(&self) -> Self::ReadValue {
572 T::try_from_raw(self.inner.read())
573 }
574}
575
576impl<T, Inner> EnumViewMut<T, Inner>
577where
578 Inner: TryWrite,
579 Inner::WriteValue: From<T>,
580{
581 pub fn try_write(&mut self, val: T) -> Result<(), Error> {
582 self.inner.try_write(Inner::WriteValue::from(val))
583 }
584}
585
586impl<T, Inner> InfallibleWrite for EnumViewMut<T, Inner>
587where
588 Inner: InfallibleWrite,
589 Inner::WriteValue: From<T>,
590{
591 type WriteValue = T;
592 type Output = EnumViewMut<T, Inner::Output>;
593 fn write(self, val: T) -> Self::Output {
594 EnumViewMut {
595 inner: self.inner.write(Inner::WriteValue::from(val)),
596 _phantom: core::marker::PhantomData,
597 }
598 }
599}
600
601impl<T, Inner> EnumViewMut<T, Inner>
602where
603 Inner: TryRead,
604 T: TryFromRaw<Inner::ReadValue>,
605{
606 pub fn try_read(&self) -> Result<T, Error<Inner::ReadValue>> {
607 let raw = self.inner.try_read().map_err(|e| e.map_type())?;
608 T::try_from_raw(raw)
609 }
610}
611
612impl<T, Inner> InfallibleRead for EnumViewMut<T, Inner>
613where
614 Inner: InfallibleRead,
615 T: TryFromRaw<Inner::ReadValue>,
616{
617 type ReadValue = Result<T, Error<Inner::ReadValue>>;
618 fn read(&self) -> Self::ReadValue {
619 T::try_from_raw(self.inner.read())
620 }
621}
622
623pub struct BitUInt<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State = UncheckedState> {
624 storage: S,
625 _marker: core::marker::PhantomData<(E, ST)>,
626}
627
628impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State> BitUInt<BITS, BIT_OFFSET, E, S, ST> {
629 pub fn new(storage: S) -> Self {
630 Self {
631 storage,
632 _marker: core::marker::PhantomData,
633 }
634 }
635}
636
637impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage + Clone, ST: State> Clone for BitUInt<BITS, BIT_OFFSET, E, S, ST> {
638 fn clone(&self) -> Self {
639 Self {
640 storage: self.storage.clone(),
641 _marker: core::marker::PhantomData,
642 }
643 }
644}
645
646impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State> BitUInt<BITS, BIT_OFFSET, E, S, ST>
647where
648 SizeSelector<BITS>: SmallestUInt,
649{
650 pub fn try_read(&self) -> Result<<SizeSelector<BITS> as SmallestUInt>::T, Error> {
651 let mut val: u64 = 0;
652 let first_byte = BIT_OFFSET / 8;
653 let last_byte = (BIT_OFFSET + BITS - 1) / 8;
654
655 for i in first_byte..=last_byte {
656 let byte_val = self.storage.try_read_byte(i)? as u64;
657 let bits_from_byte_offset = i * 8;
658
659 if bits_from_byte_offset >= BIT_OFFSET {
660 let shift = bits_from_byte_offset - BIT_OFFSET;
661 if shift < 64 {
662 val |= byte_val << shift;
663 }
664 } else {
665 let shift = BIT_OFFSET - bits_from_byte_offset;
666 val |= byte_val >> shift;
667 }
668 }
669
670 let mask = if BITS == 64 { !0 } else { (1 << BITS) - 1 };
671 Ok(<SizeSelector<BITS> as SmallestUInt>::from_u64(val & mask))
672 }
673}
674
675impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: IsOk> InfallibleRead for BitUInt<BITS, BIT_OFFSET, E, S, ST>
676where
677 SizeSelector<BITS>: SmallestUInt,
678{
679 type ReadValue = <SizeSelector<BITS> as SmallestUInt>::T;
680 fn read(&self) -> <SizeSelector<BITS> as SmallestUInt>::T {
681 self.try_read().expect("infallible read in ok state")
682 }
683}
684
685pub struct BitInt<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State = UncheckedState> {
686 storage: S,
687 _marker: core::marker::PhantomData<(E, ST)>,
688}
689
690impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State> BitInt<BITS, BIT_OFFSET, E, S, ST> {
691 pub fn new(storage: S) -> Self {
692 Self {
693 storage,
694 _marker: core::marker::PhantomData,
695 }
696 }
697}
698
699impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage + Clone, ST: State> Clone for BitInt<BITS, BIT_OFFSET, E, S, ST> {
700 fn clone(&self) -> Self {
701 Self {
702 storage: self.storage.clone(),
703 _marker: core::marker::PhantomData,
704 }
705 }
706}
707
708impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State> BitInt<BITS, BIT_OFFSET, E, S, ST>
709where
710 SizeSelector<BITS>: SmallestUInt + SmallestInt<U = <SizeSelector<BITS> as SmallestUInt>::T>,
711{
712 pub fn try_read(&self) -> Result<<SizeSelector<BITS> as SmallestInt>::T, Error> {
713 let uint_view = BitUInt::<BITS, BIT_OFFSET, E, S::Sliced<'_>>::new(self.storage.slice(0, (BIT_OFFSET + BITS + 7) / 8));
714 let raw = uint_view.try_read()?;
715 Ok(<SizeSelector<BITS> as SmallestInt>::sign_extend(raw, BITS))
716 }
717}
718
719impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: IsOk> InfallibleRead for BitInt<BITS, BIT_OFFSET, E, S, ST>
720where
721 SizeSelector<BITS>: SmallestUInt + SmallestInt<U = <SizeSelector<BITS> as SmallestUInt>::T>,
722{
723 type ReadValue = <SizeSelector<BITS> as SmallestInt>::T;
724 fn read(&self) -> <SizeSelector<BITS> as SmallestInt>::T {
725 self.try_read().expect("infallible read in ok state")
726 }
727}
728
729impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State> TryRead for BitUInt<BITS, BIT_OFFSET, E, S, ST>
730where
731 SizeSelector<BITS>: SmallestUInt,
732{
733 type ReadValue = <SizeSelector<BITS> as SmallestUInt>::T;
734 fn try_read(&self) -> Result<Self::ReadValue, Error> {
735 self.try_read()
736 }
737}
738
739impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State> TryRead for BitInt<BITS, BIT_OFFSET, E, S, ST>
740where
741 SizeSelector<BITS>: SmallestUInt + SmallestInt<U = <SizeSelector<BITS> as SmallestUInt>::T>,
742{
743 type ReadValue = <SizeSelector<BITS> as SmallestInt>::T;
744 fn try_read(&self) -> Result<Self::ReadValue, Error> {
745 self.try_read()
746 }
747}
748
749pub struct Flag<const BITS: usize, E: ByteOrder, S: Storage, ST: State = UncheckedState> {
750 storage: S,
751 _marker: core::marker::PhantomData<(E, ST)>,
752}
753
754impl<const BITS: usize, E: ByteOrder, S: Storage, ST: State> Flag<BITS, E, S, ST> {
755 pub fn new(storage: S) -> Self {
756 Self {
757 storage,
758 _marker: core::marker::PhantomData,
759 }
760 }
761}
762
763impl<const BITS: usize, E: ByteOrder, S: Storage + Clone, ST: State> Clone for Flag<BITS, E, S, ST> {
764 fn clone(&self) -> Self {
765 Self {
766 storage: self.storage.clone(),
767 _marker: core::marker::PhantomData,
768 }
769 }
770}
771
772impl<const BITS: usize, E: ByteOrder, S: Storage, ST: State> Flag<BITS, E, S, ST> {
773 pub fn try_read(&self) -> Result<bool, Error> {
774 let byte_val = self.storage.try_read_byte(0)?;
775 Ok((byte_val & 1) != 0)
776 }
777}
778
779impl<const BITS: usize, E: ByteOrder, S: Storage, ST: IsOk> InfallibleRead for Flag<BITS, E, S, ST> {
780 type ReadValue = bool;
781 fn read(&self) -> bool {
782 self.try_read().expect("infallible read in ok state")
783 }
784}
785
786impl<const BITS: usize, E: ByteOrder, S: Storage, ST: State> TryRead for Flag<BITS, E, S, ST> {
787 type ReadValue = bool;
788 fn try_read(&self) -> Result<Self::ReadValue, Error> {
789 self.try_read()
790 }
791}
792
793impl<const BITS: usize, E: ByteOrder, S: MutStorage, ST: State> Flag<BITS, E, S, ST> {
794 pub fn try_write(&mut self, val: bool) -> Result<(), Error> {
795 let mut byte_val = self.storage.try_read_byte(0).unwrap_or(0);
796 if val {
797 byte_val |= 1;
798 } else {
799 byte_val &= !1;
800 }
801 self.storage.try_write_byte(0, byte_val)
802 }
803}
804
805impl<const BITS: usize, E: ByteOrder, S: MutStorage, ST: State> TryWrite for Flag<BITS, E, S, ST> {
806 type WriteValue = bool;
807 fn try_write(&mut self, val: bool) -> Result<(), Error> {
808 self.try_write(val)
809 }
810}
811
812impl<const BITS: usize, E: ByteOrder, S: MutStorage, ST: IsComplete> InfallibleWrite
813 for Flag<BITS, E, S, ST>
814{
815 type WriteValue = bool;
816 type Output = Flag<BITS, E, S, ST::OnLayoutMutation>;
817 fn write(mut self, val: bool) -> Self::Output {
818 self.try_write(val).expect("infallible write in complete state");
819 Flag {
820 storage: self.storage,
821 _marker: core::marker::PhantomData,
822 }
823 }
824}
825
826pub struct BitFlag<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State = UncheckedState> {
827 storage: S,
828 _marker: core::marker::PhantomData<(E, ST)>,
829}
830
831impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State> BitFlag<BITS, BIT_OFFSET, E, S, ST> {
832 pub fn new(storage: S) -> Self {
833 Self {
834 storage,
835 _marker: core::marker::PhantomData,
836 }
837 }
838}
839
840impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage + Clone, ST: State> Clone
841 for BitFlag<BITS, BIT_OFFSET, E, S, ST>
842{
843 fn clone(&self) -> Self {
844 Self {
845 storage: self.storage.clone(),
846 _marker: core::marker::PhantomData,
847 }
848 }
849}
850
851impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State> BitFlag<BITS, BIT_OFFSET, E, S, ST> {
852 pub fn try_read(&self) -> Result<bool, Error> {
853 let byte_val = self.storage.try_read_byte(BIT_OFFSET / 8)?;
854 Ok((byte_val & (1 << (BIT_OFFSET % 8))) != 0)
855 }
856}
857
858impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: IsOk> InfallibleRead
859 for BitFlag<BITS, BIT_OFFSET, E, S, ST>
860{
861 type ReadValue = bool;
862 fn read(&self) -> bool {
863 self.try_read().expect("infallible read in ok state")
864 }
865}
866
867impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: Storage, ST: State> TryRead
868 for BitFlag<BITS, BIT_OFFSET, E, S, ST>
869{
870 type ReadValue = bool;
871 fn try_read(&self) -> Result<Self::ReadValue, Error> {
872 self.try_read()
873 }
874}
875
876impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: MutStorage, ST: State> BitFlag<BITS, BIT_OFFSET, E, S, ST> {
877 pub fn try_write(&mut self, val: bool) -> Result<(), Error> {
878 let byte_idx = BIT_OFFSET / 8;
879 let bit_in_byte = BIT_OFFSET % 8;
880 let mut byte_val = self.storage.try_read_byte(byte_idx)?;
881 if val {
882 byte_val |= 1 << bit_in_byte;
883 } else {
884 byte_val &= !(1 << bit_in_byte);
885 }
886 self.storage.try_write_byte(byte_idx, byte_val)
887 }
888}
889
890impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: MutStorage, ST: State> TryWrite
891 for BitFlag<BITS, BIT_OFFSET, E, S, ST>
892{
893 type WriteValue = bool;
894 fn try_write(&mut self, val: bool) -> Result<(), Error> {
895 self.try_write(val)
896 }
897}
898
899impl<const BITS: usize, const BIT_OFFSET: usize, E: ByteOrder, S: MutStorage, ST: IsComplete> InfallibleWrite
900 for BitFlag<BITS, BIT_OFFSET, E, S, ST>
901{
902 type WriteValue = bool;
903 type Output = BitFlag<BITS, BIT_OFFSET, E, S, ST::OnLayoutMutation>;
904 fn write(mut self, val: bool) -> Self::Output {
905 self.try_write(val).expect("infallible write in complete state");
906 BitFlag {
907 storage: self.storage,
908 _marker: core::marker::PhantomData,
909 }
910 }
911}
912
913#[derive(Clone, Copy, Debug)]
914pub struct VirtualField<T> {
915 pub value: core::result::Result<T, Error>,
916}
917
918impl<T> VirtualField<T> {
919 pub const fn new(value: core::result::Result<T, Error>) -> Self {
920 Self { value }
921 }
922}
923
924impl<T: Copy> VirtualField<T> {
925 pub fn try_read(&self) -> core::result::Result<T, Error> {
926 self.value
927 }
928
929 pub fn read(&self) -> T {
930 self.try_read().expect("infallible virtual field read in minimally complete state")
931 }
932}
933
934impl<T: Copy> TryRead for VirtualField<T> {
935 type ReadValue = T;
936 fn try_read(&self) -> core::result::Result<T, Error> {
937 self.value
938 }
939}
940
941impl<T: Copy> InfallibleRead for VirtualField<T> {
942 type ReadValue = T;
943 fn read(&self) -> T {
944 self.try_read().expect("infallible virtual field read in complete state")
945 }
946}
947