use crate::trade::intent::Intent;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Lane {
Exchange,
Staking,
}
impl Lane {
#[must_use]
pub const fn of(intent: &Intent) -> Option<Lane> {
match intent {
Intent::Stake(_) | Intent::Unstake(_) | Intent::Claim(_) => Some(Lane::Staking),
Intent::CancelIntent(_) => None,
_ => Some(Lane::Exchange),
}
}
}
#[must_use]
pub fn first(random: [u8; 3]) -> u128 {
let drawn = random.iter().fold(0u128, |number, byte| (number << 8) | u128::from(*byte));
drawn.max(1) * 256
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Nonces {
exchange: u128,
staking: u128,
}
impl Nonces {
#[must_use]
pub fn seeded(exchange: [u8; 3], staking: [u8; 3]) -> Nonces {
Nonces { exchange: first(exchange), staking: first(staking) }
}
#[must_use]
pub const fn resume(exchange: u128, staking: u128) -> Nonces {
Nonces { exchange, staking }
}
#[must_use]
pub const fn peek(&self, lane: Lane) -> u128 {
match lane {
Lane::Exchange => self.exchange,
Lane::Staking => self.staking,
}
}
pub fn take(&mut self, lane: Lane) -> u128 {
let slot = match lane {
Lane::Exchange => &mut self.exchange,
Lane::Staking => &mut self.staking,
};
let nonce = *slot;
*slot = slot.saturating_add(1);
nonce
}
}
#[cfg(test)]
#[path = "tests/nonce.rs"]
mod tests;