1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
use crate::WireItem; use std::convert::TryFrom; use std::io::{Read, Write}; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, TryFromPrimitive)] #[repr(u16)] pub enum Flag { Reward = 0, CommitOutputs = 1, } impl Flag { pub const fn flag(&self) -> u16 { 1 << *self as u16 } pub const fn in_bitvec(&self, bitvec: u16) -> bool { bitvec & self.flag() != 0 } pub const fn all() -> [Flag; 2] { use Flag::*; [Reward, CommitOutputs] } } impl std::fmt::Display for Flag { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Flag{:?}", self) } } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Type(pub u16); impl Type { pub const fn has(&self, f: Flag) -> bool { f.in_bitvec(self.0) } pub const fn is(&self, t: KnownType) -> bool { self.0 == t as u16 } pub fn has_unknown_flags(&self) -> bool { std::iter::successors(Some(15), |i| if *i > 0 { Some(i - 1) } else { None }) .filter(|i: &u16| Flag::try_from(*i).is_err()) .map(|i| 1 << i) .filter(|i| self.0 & i == 0) .next() .is_some() } } impl<T> From<T> for Type where u16: From<T>, { fn from(t: T) -> Self { Type(u16::from(t)) } } impl std::iter::FromIterator<Flag> for Type { fn from_iter<I: IntoIterator<Item = Flag>>(iter: I) -> Self { Type(iter.into_iter().fold(0_u16, |acc, x| acc & x.flag())) } } impl WireItem for Type { fn encode<W: Write>(&self, w: &mut W) -> std::io::Result<usize> { self.0.encode(w) } fn decode<R: Read>(r: &mut R) -> std::io::Result<Self> { u16::decode(r).map(Type) } } impl std::fmt::Display for Type { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.has_unknown_flags() { write!(f, "{:016b}", self.0)?; } write!(f, "[")?; let mut first = true; for flag in Flag::all().iter() { if !first { write!(f, "|")?; } else { first = false; } if self.has(*flag) { write!(f, "{}", flag)?; } else { write!(f, "No-{}", flag)?; } } write!(f, "]")?; Ok(()) } } #[derive(Clone, Copy, Debug, PartialEq, Eq, TryFromPrimitive)] #[repr(u16)] pub enum KnownType { TypeAltruistCommit = Flag::CommitOutputs.flag(), TypeRewardCommit = Flag::CommitOutputs.flag() | Flag::Reward.flag(), } impl From<KnownType> for u16 { fn from(t: KnownType) -> Self { t as u16 } } impl WireItem for KnownType { fn encode<W: Write>(&self, w: &mut W) -> std::io::Result<usize> { (*self as u16).encode(w) } fn decode<R: Read>(r: &mut R) -> std::io::Result<Self> { KnownType::try_from(u16::decode(r)?).map_err(|_| std::io::ErrorKind::InvalidData.into()) } } impl TryFrom<Type> for KnownType { type Error = Type; fn try_from(t: Type) -> Result<Self, Type> { KnownType::try_from(t.0).map_err(Type) } }