#![cfg(not(target_arch = "wasm32"))]
use std::fmt;
#[derive(Debug, Clone, Default)]
pub struct CorrelationContext {
pub session_kind: Option<String>,
pub grant_id: Option<String>,
pub scope: Option<String>,
pub peer_node_id: Option<String>,
pub connection_id: Option<String>,
pub transport_epoch: Option<String>,
pub channel: Option<String>,
pub token_fp: Option<String>,
}
impl CorrelationContext {
pub fn new() -> Self {
Self::default()
}
pub fn session_kind(mut self, value: impl Into<String>) -> Self {
self.session_kind = Some(value.into());
self
}
pub fn grant_id(mut self, value: impl Into<String>) -> Self {
self.grant_id = Some(value.into());
self
}
pub fn scope(mut self, value: impl Into<String>) -> Self {
self.scope = Some(value.into());
self
}
pub fn peer_node_id(mut self, value: impl Into<String>) -> Self {
self.peer_node_id = Some(value.into());
self
}
pub fn connection_id(mut self, value: impl Into<String>) -> Self {
self.connection_id = Some(value.into());
self
}
pub fn transport_epoch(mut self, value: impl Into<String>) -> Self {
self.transport_epoch = Some(value.into());
self
}
pub fn channel(mut self, value: impl Into<String>) -> Self {
self.channel = Some(value.into());
self
}
pub fn token_fp(mut self, value: impl Into<String>) -> Self {
self.token_fp = Some(value.into());
self
}
pub fn from_drive_grant_scope(scope: &str) -> Self {
let mut ctx = Self::new().scope(scope);
if let Some(grant_id) = scope.strip_prefix("drive-grant:") {
ctx = ctx.grant_id(grant_id);
}
ctx
}
pub fn is_empty(&self) -> bool {
self.session_kind.is_none()
&& self.grant_id.is_none()
&& self.scope.is_none()
&& self.peer_node_id.is_none()
&& self.connection_id.is_none()
&& self.transport_epoch.is_none()
&& self.channel.is_none()
&& self.token_fp.is_none()
}
}
impl fmt::Display for CorrelationContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut first = true;
let mut emit = |k: &str, v: &str| -> fmt::Result {
if !first {
write!(f, " ")?;
}
first = false;
write!(f, "{}={}", k, v)
};
if let Some(v) = &self.session_kind {
emit("session_kind", v)?;
}
if let Some(v) = &self.grant_id {
emit("grant_id", v)?;
}
if let Some(v) = &self.scope {
emit("scope", v)?;
}
if let Some(v) = &self.peer_node_id {
emit("peer_node_id", v)?;
}
if let Some(v) = &self.connection_id {
emit("connection_id", v)?;
}
if let Some(v) = &self.transport_epoch {
emit("transport_epoch", v)?;
}
if let Some(v) = &self.channel {
emit("channel", v)?;
}
if let Some(v) = &self.token_fp {
emit("token_fp", v)?;
}
Ok(())
}
}
#[macro_export]
macro_rules! clog {
($tag:expr, $ctx:expr $(,)?) => {
{
let ctx_ref: &$crate::client::correlation::CorrelationContext = $ctx;
if ctx_ref.is_empty() {
println!("{}", $tag);
} else {
println!("{} {}", $tag, ctx_ref);
}
}
};
($tag:expr, $ctx:expr, $($rest:tt)+) => {
{
let ctx_ref: &$crate::client::correlation::CorrelationContext = $ctx;
let body = format!($($rest)+);
if ctx_ref.is_empty() {
println!("{} {}", $tag, body);
} else {
println!("{} {} {}", $tag, ctx_ref, body);
}
}
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn renders_only_populated_fields() {
let ctx = CorrelationContext::new()
.session_kind("drive-grant-guest")
.scope("drive-grant:abc")
.peer_node_id("node-A");
let rendered = format!("{}", ctx);
assert_eq!(
rendered,
"session_kind=drive-grant-guest scope=drive-grant:abc peer_node_id=node-A"
);
}
#[test]
fn empty_context_renders_empty_string() {
assert_eq!(format!("{}", CorrelationContext::new()), "");
assert!(CorrelationContext::new().is_empty());
}
#[test]
fn from_drive_grant_scope_extracts_grant_id() {
let ctx = CorrelationContext::from_drive_grant_scope("drive-grant:my-grant-uuid");
assert_eq!(ctx.scope.as_deref(), Some("drive-grant:my-grant-uuid"));
assert_eq!(ctx.grant_id.as_deref(), Some("my-grant-uuid"));
}
#[test]
fn from_drive_grant_scope_leaves_grant_id_unset_for_non_grant_scopes() {
let ctx = CorrelationContext::from_drive_grant_scope("user-device");
assert_eq!(ctx.scope.as_deref(), Some("user-device"));
assert!(ctx.grant_id.is_none());
}
#[test]
fn full_field_set_orders_deterministically() {
let ctx = CorrelationContext::new()
.session_kind("drive-grant-guest")
.grant_id("g1")
.scope("drive-grant:g1")
.peer_node_id("node-A")
.connection_id("conn-1")
.transport_epoch("3")
.channel("drive-view.list")
.token_fp("ab12cd34");
let rendered = format!("{}", ctx);
assert_eq!(
rendered,
"session_kind=drive-grant-guest grant_id=g1 scope=drive-grant:g1 \
peer_node_id=node-A connection_id=conn-1 transport_epoch=3 \
channel=drive-view.list token_fp=ab12cd34"
);
}
}