Skip to main content

emboss_runtime/
lib.rs

1// Copyright 2026 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15pub 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
22/// Trait for safe signed-to-unsigned and mixed-integer comparisons.
23pub 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
494/// Trait implemented by Emboss struct and bitfield views.
495pub trait View {
496    /// Returns the intrinsic layout size of the structure in bytes.
497    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