cdk_common/
state.rs

1//! State transition rules
2
3use cashu::State;
4
5/// State transition Error
6#[derive(thiserror::Error, Debug)]
7pub enum Error {
8    /// Pending Token
9    #[error("Token already pending for another update")]
10    Pending,
11    /// Already spent
12    #[error("Token already spent")]
13    AlreadySpent,
14    /// Invalid transition
15    #[error("Invalid transition: From {0} to {1}")]
16    InvalidTransition(State, State),
17}
18
19#[inline]
20/// Check if the state transition is allowed
21pub fn check_state_transition(current_state: State, new_state: State) -> Result<(), Error> {
22    let is_valid_transition = match current_state {
23        State::Unspent => matches!(new_state, State::Pending | State::Spent),
24        State::Pending => matches!(new_state, State::Unspent | State::Spent),
25        // Any other state shouldn't be updated by the mint, and the wallet does not use this
26        // function
27        _ => false,
28    };
29
30    if !is_valid_transition {
31        Err(match current_state {
32            State::Pending => Error::Pending,
33            State::Spent => Error::AlreadySpent,
34            _ => Error::InvalidTransition(current_state, new_state),
35        })
36    } else {
37        Ok(())
38    }
39}