celestia_types/share/
info_byte.rs

1use crate::consts::appconsts;
2use crate::{Error, Result};
3
4#[cfg(feature = "uniffi")]
5use crate::error::UniffiResult;
6
7/// The part of [`Share`] containing the `version` and `sequence_start` information.
8///
9/// [`InfoByte`] is a single byte with the following structure:
10///
11///  - the first 7 bits are reserved for version information in big endian form
12///  - last bit is a `sequence_start` flag. If it's set then this [`Share`] is
13///    a first of a sequence, otherwise it's a continuation share.
14///
15///  [`Share`]: crate::Share
16#[repr(transparent)]
17#[derive(Debug, PartialEq)]
18#[cfg_attr(feature = "uniffi", derive(uniffi::Object))]
19pub struct InfoByte(u8);
20
21impl InfoByte {
22    /// Create a new [`InfoByte`] with given version and `sequence_start`.
23    pub fn new(version: u8, is_sequence_start: bool) -> Result<Self> {
24        if version > appconsts::MAX_SHARE_VERSION {
25            Err(Error::MaxShareVersionExceeded(version))
26        } else {
27            let prefix = version << 1;
28            let sequence_start = if is_sequence_start { 1 } else { 0 };
29            Ok(Self(prefix + sequence_start))
30        }
31    }
32
33    /// Get the `version`.
34    pub fn version(&self) -> u8 {
35        self.0 >> 1
36    }
37
38    /// Get the `sequence_start` indicator.
39    pub fn is_sequence_start(&self) -> bool {
40        self.0 % 2 == 1
41    }
42
43    /// Convert the [`InfoByte`] to a byte.
44    pub fn as_u8(&self) -> u8 {
45        self.0
46    }
47
48    pub(crate) fn from_raw(byte: u8) -> Result<Self> {
49        let version = byte >> 1;
50        if version > appconsts::MAX_SHARE_VERSION {
51            Err(Error::MaxShareVersionExceeded(version))
52        } else {
53            Ok(InfoByte(byte))
54        }
55    }
56
57    pub(crate) fn from_raw_unchecked(byte: u8) -> Self {
58        InfoByte(byte)
59    }
60}
61
62#[cfg(feature = "uniffi")]
63#[uniffi::export]
64impl InfoByte {
65    /// Create a new [`InfoByte`] with given version and `sequence_start`.
66    #[uniffi::constructor(name = "create")]
67    pub fn uniffi_new(version: u8, is_sequence_start: bool) -> UniffiResult<Self> {
68        Ok(InfoByte::new(version, is_sequence_start)?)
69    }
70
71    /// Get the `version`.
72    #[uniffi::method(name = "version")]
73    pub fn uniffi_version(&self) -> u8 {
74        self.version()
75    }
76
77    /// Get the `sequence_start` indicator.
78    #[uniffi::method(name = "is_sequence_start")]
79    pub fn uniffi_is_sequence_start(&self) -> bool {
80        self.is_sequence_start()
81    }
82
83    /// Convert the [`InfoByte`] to a byte.
84    #[uniffi::method(name = "as_u8")]
85    pub fn uniffi_as_u8(&self) -> u8 {
86        self.as_u8()
87    }
88}