use core::marker::PhantomData;
use crate::ProtocolError;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Decoded;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Canonical;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ForkValidated;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct SenderRecovered;
#[derive(Debug, Eq, PartialEq)]
pub struct CanonicalValidationProof {
_private: (),
}
impl CanonicalValidationProof {
#[must_use]
#[cfg(test)]
pub(crate) const fn new() -> Self {
Self { _private: () }
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct ForkValidationProof {
_private: (),
}
impl ForkValidationProof {
#[must_use]
#[cfg(test)]
pub(crate) const fn new() -> Self {
Self { _private: () }
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct SenderRecoveryProof {
_private: (),
}
impl SenderRecoveryProof {
#[must_use]
#[cfg(test)]
pub(crate) const fn new() -> Self {
Self { _private: () }
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct StateTransitionError<State> {
transaction: Transaction<State>,
error: ProtocolError,
}
impl<State> StateTransitionError<State> {
const fn new(transaction: Transaction<State>, error: ProtocolError) -> Self {
Self { transaction, error }
}
#[must_use]
pub const fn error(&self) -> ProtocolError {
self.error
}
#[must_use]
pub fn into_parts(self) -> (Transaction<State>, ProtocolError) {
(self.transaction, self.error)
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Transaction<State> {
_state: PhantomData<State>,
}
impl<State> Transaction<State> {
const fn new() -> Self {
Self {
_state: PhantomData,
}
}
}
impl Transaction<Decoded> {
#[must_use]
#[cfg(test)]
pub(crate) const fn decoded() -> Self {
Self::new()
}
pub fn try_into_canonical(
self,
proof: Result<CanonicalValidationProof, ProtocolError>,
) -> Result<Transaction<Canonical>, StateTransitionError<Decoded>> {
if let Err(error) = proof {
return Err(StateTransitionError::new(self, error));
}
Ok(Transaction::new())
}
}
impl Transaction<Canonical> {
pub fn try_into_fork_validated(
self,
proof: Result<ForkValidationProof, ProtocolError>,
) -> Result<Transaction<ForkValidated>, StateTransitionError<Canonical>> {
if let Err(error) = proof {
return Err(StateTransitionError::new(self, error));
}
Ok(Transaction::new())
}
}
impl Transaction<ForkValidated> {
pub fn try_into_sender_recovered(
self,
proof: Result<SenderRecoveryProof, ProtocolError>,
) -> Result<Transaction<SenderRecovered>, StateTransitionError<ForkValidated>> {
if let Err(error) = proof {
return Err(StateTransitionError::new(self, error));
}
Ok(Transaction::new())
}
}
#[cfg(test)]
#[path = "state_tests.rs"]
mod tests;