statsig_rust/event_logging_adapter/
log_event_payload.rs1use serde::{Deserialize, Serialize};
2use serde_json::{from_value, json, Value};
3use std::collections::HashSet;
4
5use crate::{event_logging::statsig_event_internal::StatsigEventInternal, StatsigErr};
6
7#[derive(Clone, Serialize, Deserialize)]
8#[serde(rename_all = "camelCase")]
9pub struct LogEventPayload {
10 pub events: Value,
11 pub statsig_metadata: Value,
12}
13
14#[derive(Serialize, Deserialize)]
15#[serde(rename_all = "camelCase")]
16pub struct LogEventRequest {
17 pub payload: LogEventPayload,
18 pub event_count: u64,
19}
20
21impl LogEventRequest {
22 pub fn merge(&mut self, other: &LogEventRequest) -> Result<(), StatsigErr> {
23 let right = parse_events(&self.payload.events)?;
24 let left = parse_events(&other.payload.events)?;
25
26 let mut expo_keys = HashSet::new();
27 let mut merged_events = vec![];
28
29 merge_event_into(right, &mut expo_keys, &mut merged_events);
30 merge_event_into(left, &mut expo_keys, &mut merged_events);
31
32 self.payload.events = json!(merged_events);
33 self.event_count = merged_events.len() as u64;
34
35 Ok(())
36 }
37}
38
39fn parse_events(events: &Value) -> Result<Vec<StatsigEventInternal>, StatsigErr> {
40 match from_value(events.clone()) {
41 Ok(events) => Ok(events),
42 Err(e) => Err(StatsigErr::JsonParseError(
43 stringify!(Vec<StatsigEventInternal>).to_string(),
44 e.to_string(),
45 )),
46 }
47}
48
49fn merge_event_into(
50 events: Vec<StatsigEventInternal>,
51 expo_keys: &mut HashSet<String>,
52 merged_events: &mut Vec<StatsigEventInternal>,
53) {
54 for event in events {
55 if event.is_exposure_event() {
56 let key = create_merge_key(&event);
57 if expo_keys.contains(&key) {
58 continue;
59 }
60 expo_keys.insert(key);
61 }
62
63 merged_events.push(event);
64 }
65}
66
67fn create_merge_key(event: &StatsigEventInternal) -> String {
68 let mut metadata_string = String::new();
69 if let Some(metadata) = &event.event_data.metadata {
70 metadata_string = metadata
71 .values()
72 .cloned()
73 .collect::<Vec<String>>()
74 .join(",");
75 }
76
77 format!(
78 "{}|{}|{}",
79 event.event_data.event_name, event.user.value, metadata_string
80 )
81}