use serde_json::{json, Map, Value};
pub const EVENT_SCHEMA_VERSION: u32 = 1;
#[derive(Debug, Clone)]
pub struct SuperProps {
pub client_version: &'static str,
pub os: &'static str,
pub agent_id: String,
pub session_id: String,
pub authenticated: bool,
}
impl SuperProps {
pub fn new(agent_id: String, authenticated: bool) -> Self {
Self {
client_version: env!("CARGO_PKG_VERSION"),
os: os_tag(),
agent_id,
session_id: format!("sess_{}", uuid::Uuid::now_v7().simple()),
authenticated,
}
}
pub fn merge_into(&self, props: &mut Map<String, Value>) {
props.insert("client_version".into(), json!(self.client_version));
props.insert("os".into(), json!(self.os));
props.insert("agent_id".into(), json!(self.agent_id));
props.insert("session_id".into(), json!(self.session_id));
props.insert("authenticated".into(), json!(self.authenticated));
props.insert("event_schema_version".into(), json!(EVENT_SCHEMA_VERSION));
props.insert(
"$insert_id".into(),
json!(format!("ins_{}", uuid::Uuid::now_v7().simple())),
);
}
}
const fn os_tag() -> &'static str {
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
{
"darwin-arm64"
}
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
{
"darwin-x64"
}
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
{
"linux-x64"
}
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
{
"linux-arm64"
}
#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
{
"win32-x64"
}
#[cfg(not(any(
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "linux", target_arch = "aarch64"),
all(target_os = "windows", target_arch = "x86_64"),
)))]
{
"unknown"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_merge_into_attaches_all_fields() {
let sp = SuperProps::new("agt_deadbeef".into(), false);
let mut props = Map::new();
sp.merge_into(&mut props);
assert!(props.contains_key("client_version"));
assert!(props.contains_key("os"));
assert_eq!(props["agent_id"], "agt_deadbeef");
assert!(props.contains_key("session_id"));
assert_eq!(props["authenticated"], false);
assert_eq!(props["event_schema_version"], 1);
assert!(props.contains_key("$insert_id"));
}
#[test]
fn test_session_id_is_unique_per_instance() {
let a = SuperProps::new("agt_x".into(), true);
let b = SuperProps::new("agt_x".into(), true);
assert_ne!(a.session_id, b.session_id);
}
#[test]
fn test_os_tag_is_known_value() {
let tag = os_tag();
let supported = [
"darwin-arm64",
"darwin-x64",
"linux-x64",
"linux-arm64",
"win32-x64",
];
if tag == "unknown" {
assert_eq!(tag, "unknown");
} else {
assert!(supported.contains(&tag), "unexpected os tag: {tag}");
}
}
}