use std::{fmt, sync::Arc};
macro_rules! string_id {
($name:ident) => {
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct $name(Arc<str>);
impl $name {
pub fn new(value: impl Into<Arc<str>>) -> Self {
Self(value.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl From<&str> for $name {
fn from(value: &str) -> Self {
Self::new(value)
}
}
impl From<String> for $name {
fn from(value: String) -> Self {
Self::new(value)
}
}
impl fmt::Display for $name {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(&self.0)
}
}
};
}
string_id!(ApplicationId);
string_id!(ModuleId);
string_id!(ServiceId);
string_id!(OperationId);
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct TraceId(u128);
impl TraceId {
pub const fn from_u128(value: u128) -> Self {
Self(value)
}
pub const fn as_u128(self) -> u128 {
self.0
}
}
impl fmt::Display for TraceId {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{:032x}", self.0)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct SpanId(u64);
impl SpanId {
pub const fn from_u64(value: u64) -> Self {
Self(value)
}
pub const fn as_u64(self) -> u64 {
self.0
}
}
impl fmt::Display for SpanId {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{:016x}", self.0)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CallContext {
application: ApplicationId,
module: ModuleId,
service: ServiceId,
operation: OperationId,
trace_id: TraceId,
span_id: SpanId,
}
impl CallContext {
pub fn new(
application: ApplicationId,
module: ModuleId,
service: ServiceId,
operation: OperationId,
trace_id: TraceId,
span_id: SpanId,
) -> Self {
Self {
application,
module,
service,
operation,
trace_id,
span_id,
}
}
pub fn application(&self) -> &ApplicationId {
&self.application
}
pub fn module(&self) -> &ModuleId {
&self.module
}
pub fn service(&self) -> &ServiceId {
&self.service
}
pub fn operation(&self) -> &OperationId {
&self.operation
}
pub const fn trace_id(&self) -> TraceId {
self.trace_id
}
pub const fn span_id(&self) -> SpanId {
self.span_id
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn identifiers_have_stable_display_forms() {
assert_eq!(TraceId::from_u128(42).to_string().len(), 32);
assert_eq!(SpanId::from_u64(42).to_string().len(), 16);
assert_eq!(ServiceId::from("orders").to_string(), "orders");
}
}