use std::fmt;
use crate::error::{Error, Result};
use crate::value::Value;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct PromiseId(pub u64);
impl fmt::Display for PromiseId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "p{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum PromiseState {
Pending,
Resolved(Value),
Rejected(crate::error::Error),
Cancelled,
}
impl PromiseState {
pub fn is_settled(&self) -> bool {
!matches!(self, PromiseState::Pending)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct PromiseRecord {
pub id: PromiseId,
pub state: PromiseState,
pub waiters: u32,
pub lane: u64,
}
impl PromiseRecord {
pub fn new(id: PromiseId, lane: u64) -> Self {
Self {
id,
state: PromiseState::Pending,
waiters: 0,
lane,
}
}
pub fn resolve(&mut self, value: Value) -> Result<()> {
match self.state {
PromiseState::Pending => {
self.state = PromiseState::Resolved(value);
Ok(())
}
_ => Err(Error::PromiseAlreadyResolved(self.id.0)),
}
}
pub fn reject(&mut self, error: crate::error::Error) -> Result<()> {
match self.state {
PromiseState::Pending => {
self.state = PromiseState::Rejected(error);
Ok(())
}
_ => Err(Error::PromiseAlreadyResolved(self.id.0)),
}
}
pub fn cancel(&mut self) -> Result<()> {
match self.state {
PromiseState::Pending => {
self.state = PromiseState::Cancelled;
Ok(())
}
_ => Err(Error::PromiseAlreadyResolved(self.id.0)),
}
}
pub fn value(&self) -> Result<Value> {
match &self.state {
PromiseState::Resolved(value) => Ok(value.clone()),
PromiseState::Pending => Err(Error::UnresolvablePromise(self.id.0)),
PromiseState::Rejected(error) => Err(error.clone()),
PromiseState::Cancelled => Err(Error::PromiseCancelled(self.id.0)),
}
}
}