ark_serialize/
flags.rs

1/// Represents metadata to be appended to an object's serialization. For
2/// example, when serializing elliptic curve points, one can
3/// use a `Flag` to represent whether the serialization is the point
4/// at infinity, or whether the `y` coordinate is positive or not.
5/// These bits will be appended to the end of the point's serialization,
6/// or included in a new byte, depending on space available.
7///
8/// This is meant to be provided to `CanonicalSerializeWithFlags` and
9/// `CanonicalDeserializeWithFlags`
10pub trait Flags: Default + Clone + Copy + Sized {
11    /// The number of bits required to encode `Self`.
12    /// This should be at most 8.
13    const BIT_SIZE: usize;
14
15    // Returns a bit mask corresponding to `self`.
16    // For example, if `Self` contains two variants, there are just two possible
17    // bit masks: `0` and `1 << 7`.
18    fn u8_bitmask(&self) -> u8;
19
20    // Tries to read `Self` from `value`. Should return `None` if the
21    // `Self::BIT_SIZE` most-significant bits of `value` do not correspond to
22    // those generated by `u8_bitmask`.
23    //
24    // That is, this method ignores all but the top `Self::BIT_SIZE` bits, and
25    // decides whether these top bits correspond to a bitmask output by
26    // `u8_bitmask`.
27    fn from_u8(value: u8) -> Option<Self>;
28
29    // Convenience method that reads `Self` from `value`, just like `Self::from_u8`,
30    // but additionally zeroes out the bits corresponding to the resulting flag
31    // in `value`. If `Self::from_u8(*value)` would return `None`, then this
32    // method should *not* modify `value`.
33    fn from_u8_remove_flags(value: &mut u8) -> Option<Self> {
34        let flags = Self::from_u8(*value);
35        if let Some(f) = flags {
36            *value &= !f.u8_bitmask();
37        }
38        flags
39    }
40}
41
42/// Flags to be encoded into the serialization.
43#[derive(Default, Clone, Copy, PartialEq, Eq)]
44pub struct EmptyFlags;
45
46impl Flags for EmptyFlags {
47    const BIT_SIZE: usize = 0;
48
49    #[inline]
50    fn u8_bitmask(&self) -> u8 {
51        0
52    }
53
54    #[inline]
55    fn from_u8(_: u8) -> Option<Self> {
56        Some(EmptyFlags)
57    }
58}