/ utilities / src / serialize / flags.rs
flags.rs
  1  // Copyright (c) 2019-2025 Alpha-Delta Network Inc.
  2  // This file is part of the alphavm library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  use crate::serialize::Flags;
 17  
 18  /// Flags to be encoded into the serialization.
 19  #[derive(Default, Clone, Copy, PartialEq, Eq)]
 20  pub struct EmptyFlags;
 21  
 22  impl Flags for EmptyFlags {
 23      const BIT_SIZE: usize = 0;
 24  
 25      #[inline]
 26      fn u8_bitmask(&self) -> u8 {
 27          0
 28      }
 29  
 30      #[inline]
 31      fn from_u8(value: u8) -> Option<Self> {
 32          if (value >> 7) == 0 { Some(EmptyFlags) } else { None }
 33      }
 34  }
 35  
 36  /// Flags to be encoded into the serialization.
 37  /// The default flags (empty) should not change the binary representation.
 38  #[derive(Clone, Copy, Default, PartialEq, Eq)]
 39  pub enum SWFlags {
 40      Infinity,
 41      PositiveY,
 42      #[default]
 43      NegativeY,
 44  }
 45  
 46  impl SWFlags {
 47      #[inline]
 48      pub fn infinity() -> Self {
 49          SWFlags::Infinity
 50      }
 51  
 52      #[inline]
 53      pub fn from_y_sign(is_positive: bool) -> Self {
 54          if is_positive { SWFlags::PositiveY } else { SWFlags::NegativeY }
 55      }
 56  
 57      #[inline]
 58      pub fn is_infinity(&self) -> bool {
 59          matches!(self, SWFlags::Infinity)
 60      }
 61  
 62      #[inline]
 63      pub fn is_positive(&self) -> Option<bool> {
 64          match self {
 65              SWFlags::Infinity => None,
 66              SWFlags::PositiveY => Some(true),
 67              SWFlags::NegativeY => Some(false),
 68          }
 69      }
 70  }
 71  
 72  impl Flags for SWFlags {
 73      const BIT_SIZE: usize = 2;
 74  
 75      #[inline]
 76      fn u8_bitmask(&self) -> u8 {
 77          let mut mask = 0;
 78          match self {
 79              SWFlags::Infinity => mask |= 1 << 6,
 80              SWFlags::PositiveY => mask |= 1 << 7,
 81              _ => (),
 82          }
 83          mask
 84      }
 85  
 86      #[inline]
 87      fn from_u8(value: u8) -> Option<Self> {
 88          let x_sign = (value >> 7) & 1 == 1;
 89          let is_infinity = (value >> 6) & 1 == 1;
 90          match (x_sign, is_infinity) {
 91              // This is invalid because we only want *one* way to serialize
 92              // the point at infinity.
 93              (true, true) => None,
 94              (false, true) => Some(SWFlags::Infinity),
 95              (true, false) => Some(SWFlags::PositiveY),
 96              (false, false) => Some(SWFlags::NegativeY),
 97          }
 98      }
 99  }
100  
101  /// Flags to be encoded into the serialization.
102  /// The default flags (empty) should not change the binary representation.
103  #[derive(Clone, Copy, Default, PartialEq, Eq)]
104  pub enum EdwardsFlags {
105      PositiveY,
106      #[default]
107      NegativeY,
108  }
109  
110  impl EdwardsFlags {
111      #[inline]
112      pub fn from_y_sign(is_positive: bool) -> Self {
113          if is_positive { EdwardsFlags::PositiveY } else { EdwardsFlags::NegativeY }
114      }
115  
116      #[inline]
117      pub fn is_positive(&self) -> bool {
118          match self {
119              EdwardsFlags::PositiveY => true,
120              EdwardsFlags::NegativeY => false,
121          }
122      }
123  }
124  
125  impl Flags for EdwardsFlags {
126      const BIT_SIZE: usize = 1;
127  
128      #[inline]
129      fn u8_bitmask(&self) -> u8 {
130          let mut mask = 0;
131          if let Self::PositiveY = self {
132              mask |= 1 << 7;
133          }
134          mask
135      }
136  
137      #[inline]
138      fn from_u8(value: u8) -> Option<Self> {
139          let x_sign = (value >> 7) & 1 == 1;
140          if x_sign { Some(Self::PositiveY) } else { Some(Self::NegativeY) }
141      }
142  }