use std::cell::RefCell;
thread_local! {
static CURRENT_SESSION: RefCell<Option<String>> = const { RefCell::new(None) };
}
pub fn set_session(session: Option<String>) {
CURRENT_SESSION.with(|s| {
*s.borrow_mut() = session;
});
}
struct SessionGuard(Option<String>);
impl Drop for SessionGuard {
fn drop(&mut self) {
set_session(self.0.take());
}
}
pub fn with_session<T>(session: Option<String>, f: impl FnOnce() -> T) -> T {
let prev = current_session();
set_session(session);
let _guard = SessionGuard(prev);
f()
}
pub fn current_session() -> Option<String> {
CURRENT_SESSION.with(|s| s.borrow().clone())
}
pub fn session_prefix() -> String {
CURRENT_SESSION.with(|s| match s.borrow().as_deref() {
Some(sid) if sid.starts_with("ses_") => format!("[{}] ", sid),
Some(sid) => format!("[ses_{}] ", sid),
None => String::new(),
})
}
#[macro_export]
macro_rules! slog_info {
($($arg:tt)*) => {
log::info!("[aft] {}{}", $crate::log_ctx::session_prefix(), format!($($arg)*))
};
}
#[macro_export]
macro_rules! slog_warn {
($($arg:tt)*) => {
log::warn!("[aft] {}{}", $crate::log_ctx::session_prefix(), format!($($arg)*))
};
}
#[macro_export]
macro_rules! slog_error {
($($arg:tt)*) => {
log::error!("[aft] {}{}", $crate::log_ctx::session_prefix(), format!($($arg)*))
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn with_session_sets_and_clears() {
CURRENT_SESSION.with(|s| {
assert!(s.borrow().is_none());
});
with_session(Some("test123".to_string()), || {
CURRENT_SESSION.with(|s| {
assert_eq!(s.borrow().as_deref(), Some("test123"));
});
});
CURRENT_SESSION.with(|s| {
assert!(s.borrow().is_none());
});
}
#[test]
fn with_session_none_is_noop() {
with_session(None, || {
CURRENT_SESSION.with(|s| {
assert!(s.borrow().is_none());
});
});
}
#[test]
fn session_prefix_format() {
with_session(Some("abcd1234".to_string()), || {
assert_eq!(session_prefix(), "[ses_abcd1234] ");
});
assert_eq!(session_prefix(), "");
}
#[test]
fn session_prefix_does_not_double_prefix_real_ids() {
with_session(Some("ses_313660571ffeZTsf4koSJwk50Q".to_string()), || {
assert_eq!(session_prefix(), "[ses_313660571ffeZTsf4koSJwk50Q] ");
});
}
#[test]
fn set_session_direct() {
set_session(Some("direct".to_string()));
CURRENT_SESSION.with(|s| {
assert_eq!(s.borrow().as_deref(), Some("direct"));
});
set_session(None);
CURRENT_SESSION.with(|s| {
assert!(s.borrow().is_none());
});
}
}