use bytes::Bytes;
use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ContainerId(String);
impl ContainerId {
pub fn new(id: impl Into<String>) -> Self {
ContainerId(id.into())
}
pub fn generate() -> Self {
ContainerId(format!("ramqp-{}", uuid::Uuid::new_v4()))
}
pub fn as_str(&self) -> &str {
&self.0
}
pub fn into_inner(self) -> String {
self.0
}
}
impl std::fmt::Display for ContainerId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
impl From<&str> for ContainerId {
fn from(s: &str) -> Self {
ContainerId(s.to_owned())
}
}
impl From<String> for ContainerId {
fn from(s: String) -> Self {
ContainerId(s)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ChannelId(pub u16);
impl ChannelId {
pub fn value(self) -> u16 {
self.0
}
}
impl From<u16> for ChannelId {
fn from(v: u16) -> Self {
ChannelId(v)
}
}
impl std::fmt::Display for ChannelId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ch:{}", self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Handle(pub u32);
impl Handle {
pub fn value(self) -> u32 {
self.0
}
}
impl From<u32> for Handle {
fn from(v: u32) -> Self {
Handle(v)
}
}
impl std::fmt::Display for Handle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "h:{}", self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct DeliveryId(pub u32);
impl DeliveryId {
pub fn value(self) -> u32 {
self.0
}
pub fn next(self) -> DeliveryId {
DeliveryId(self.0.wrapping_add(1))
}
}
impl From<u32> for DeliveryId {
fn from(v: u32) -> Self {
DeliveryId(v)
}
}
impl std::fmt::Display for DeliveryId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "d:{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct DeliveryTag(pub Bytes);
impl DeliveryTag {
pub fn new(bytes: impl Into<Bytes>) -> Self {
DeliveryTag(bytes.into())
}
pub fn from_u64(n: u64) -> Self {
DeliveryTag(Bytes::copy_from_slice(&n.to_be_bytes()))
}
pub fn as_bytes(&self) -> &Bytes {
&self.0
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LinkName(String);
impl LinkName {
pub fn new(name: impl Into<String>) -> Self {
LinkName(name.into())
}
pub fn generate(prefix: &str) -> Self {
LinkName(format!("{prefix}-{}", uuid::Uuid::new_v4()))
}
pub fn as_str(&self) -> &str {
&self.0
}
pub fn into_inner(self) -> String {
self.0
}
}
impl std::fmt::Display for LinkName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SessionId(pub u64);
impl SessionId {
pub fn next() -> Self {
static COUNTER: AtomicU64 = AtomicU64::new(1);
SessionId(COUNTER.fetch_add(1, Ordering::Relaxed))
}
pub fn value(self) -> u64 {
self.0
}
}
impl std::fmt::Display for SessionId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "s:{}", self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn newtypes_are_distinct_and_display() {
let c = ChannelId::from(3);
let h = Handle::from(3);
assert_eq!(c.value(), 3);
assert_eq!(h.value(), 3);
assert_eq!(c.to_string(), "ch:3");
assert_eq!(h.to_string(), "h:3");
assert_eq!(DeliveryId(5).next(), DeliveryId(6));
assert_eq!(DeliveryId(u32::MAX).next(), DeliveryId(0));
}
#[test]
fn session_ids_are_unique() {
let a = SessionId::next();
let b = SessionId::next();
assert_ne!(a, b);
}
#[test]
fn delivery_tag_from_u64() {
assert_eq!(DeliveryTag::from_u64(1).as_bytes().len(), 8);
}
}