use std::fmt;
use serde::{Deserialize, Serialize};
use crate::Error;
pub(crate) const REQUEST_ID_FLOOR: i32 = 1_500_000_000;
pub(crate) const REQUEST_ID_CEILING: i32 = i32::MAX - 1;
pub(crate) const UNSPECIFIED_REQUEST_ID: i32 = -1;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
pub(crate) struct RequestId(i32);
impl RequestId {
pub(crate) fn from_raw(id: i32) -> Option<Self> {
(id >= REQUEST_ID_FLOOR).then_some(Self(id))
}
pub(crate) fn raw(self) -> i32 {
self.0
}
}
#[cfg(test)]
impl RequestId {
pub(crate) const fn nth(n: i32) -> Self {
Self(REQUEST_ID_FLOOR + n)
}
}
impl fmt::Display for RequestId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct OrderId(pub i32);
impl OrderId {
pub fn new(id: i32) -> Self {
Self(id)
}
pub fn value(&self) -> i32 {
self.0
}
pub(crate) fn checked(self) -> Result<Self, Error> {
if self.0 >= REQUEST_ID_FLOOR {
Err(Error::OrderIdInRequestRange { order_id: self.0 })
} else {
Ok(self)
}
}
}
impl fmt::Display for OrderId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl From<i32> for OrderId {
fn from(id: i32) -> Self {
Self(id)
}
}
impl From<OrderId> for i32 {
fn from(id: OrderId) -> i32 {
id.0
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(crate) enum WireId {
Request(RequestId),
Order(OrderId),
}
impl fmt::Display for WireId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Request(id) => id.fmt(f),
Self::Order(id) => id.fmt(f),
}
}
}
impl WireId {
pub(crate) fn classify(id: i32) -> Option<Self> {
if id == UNSPECIFIED_REQUEST_ID {
None
} else if let Some(request_id) = RequestId::from_raw(id) {
Some(Self::Request(request_id))
} else {
Some(Self::Order(OrderId(id)))
}
}
}
#[cfg(test)]
#[path = "ids_tests.rs"]
mod tests;