use std::fmt;
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct ConversationId(u64);
impl ConversationId {
#[must_use]
pub fn mint() -> Self {
let bytes = *Uuid::new_v4().as_bytes();
let mut raw = [0u8; 8];
raw.copy_from_slice(&bytes[..8]);
Self(u64::from_le_bytes(raw))
}
pub(crate) const fn to_wire(self) -> u64 {
self.0
}
}
impl fmt::Display for ConversationId {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.0)
}
}
impl FromStr for ConversationId {
type Err = std::num::ParseIntError;
fn from_str(value: &str) -> Result<Self, Self::Err> {
Ok(Self(value.parse()?))
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct CorrelationId(Uuid);
impl CorrelationId {
#[must_use]
pub fn mint() -> Self {
Self(Uuid::new_v4())
}
}
impl fmt::Display for CorrelationId {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.0)
}
}
impl FromStr for CorrelationId {
type Err = uuid::Error;
fn from_str(value: &str) -> Result<Self, Self::Err> {
Ok(Self(Uuid::parse_str(value)?))
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct PublicationId(Uuid);
impl PublicationId {
#[must_use]
pub const fn from_bytes(bytes: [u8; 16]) -> Self {
Self(Uuid::from_bytes(bytes))
}
#[must_use]
pub const fn to_bytes(self) -> [u8; 16] {
*self.0.as_bytes()
}
#[must_use]
pub fn mint() -> Self {
Self(Uuid::new_v4())
}
pub(crate) const fn to_correlation(self) -> CorrelationId {
CorrelationId(self.0)
}
pub(crate) const fn from_correlation(correlation: CorrelationId) -> Self {
Self(correlation.0)
}
}
impl fmt::Display for PublicationId {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.0)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct ParticipantRef(u64);
impl ParticipantRef {
pub(crate) const fn from_wire(raw: u64) -> Self {
Self(raw)
}
pub(crate) const fn to_wire(self) -> u64 {
self.0
}
}
impl fmt::Display for ParticipantRef {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.0)
}
}
#[derive(
Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default,
)]
#[serde(transparent)]
pub struct ConversationSeq(u64);
impl ConversationSeq {
#[must_use]
pub const fn new(value: u64) -> Self {
Self(value)
}
#[must_use]
pub const fn value(self) -> u64 {
self.0
}
}
impl fmt::Display for ConversationSeq {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.0)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum PatternId {
RequestResponse,
Subscription,
PubSub,
}
impl PatternId {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::RequestResponse => "frame:conv-request@v1",
Self::Subscription => "frame:conv-subscription@v1",
Self::PubSub => "frame:conv-pubsub@v1",
}
}
#[must_use]
pub fn parse_exact(value: &str) -> Option<Self> {
match value {
"frame:conv-request@v1" => Some(Self::RequestResponse),
"frame:conv-subscription@v1" => Some(Self::Subscription),
"frame:conv-pubsub@v1" => Some(Self::PubSub),
_ => None,
}
}
#[must_use]
pub const fn allows(self, kind: MessageKind) -> bool {
match self {
Self::RequestResponse => matches!(kind, MessageKind::Request | MessageKind::Reply),
Self::Subscription | Self::PubSub => matches!(kind, MessageKind::Event),
}
}
}
impl fmt::Display for PatternId {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.as_str())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum MessageKind {
Request,
Reply,
Event,
}
impl MessageKind {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Request => "request",
Self::Reply => "reply",
Self::Event => "event",
}
}
#[must_use]
pub fn parse_exact(value: &str) -> Option<Self> {
match value {
"request" => Some(Self::Request),
"reply" => Some(Self::Reply),
"event" => Some(Self::Event),
_ => None,
}
}
}
impl fmt::Display for MessageKind {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.as_str())
}
}