tauri_plugin_auditaur/
ipc.rs1use serde::Deserialize;
2
3pub const IPC_CONTEXT_ARG: &str = "auditaurTraceContext";
5
6#[derive(Debug, Clone, Deserialize)]
11pub struct IpcTraceContext {
12 traceparent: Option<String>,
13}
14
15impl IpcTraceContext {
16 pub fn traceparent(&self) -> Option<&str> {
18 self.traceparent
19 .as_deref()
20 .filter(|value| is_w3c_traceparent(value))
21 }
22}
23
24pub fn ipc_traceparent(context: Option<&IpcTraceContext>) -> &str {
26 context
27 .and_then(IpcTraceContext::traceparent)
28 .unwrap_or_default()
29}
30
31fn is_w3c_traceparent(value: &str) -> bool {
32 let mut parts = value.split('-');
33 let version = parts.next();
34 let trace_id = parts.next();
35 let parent_span_id = parts.next();
36 let flags = parts.next();
37 parts.next().is_none()
38 && version.is_some_and(|value| is_hex_len(value, 2))
39 && trace_id.is_some_and(|value| is_hex_len(value, 32))
40 && parent_span_id.is_some_and(|value| is_hex_len(value, 16))
41 && flags.is_some_and(|value| is_hex_len(value, 2))
42}
43
44fn is_hex_len(value: &str, len: usize) -> bool {
45 value.len() == len && value.bytes().all(|byte| byte.is_ascii_hexdigit())
46}
47
48#[cfg(test)]
49mod tests {
50 use super::{ipc_traceparent, IpcTraceContext};
51 use serde_json::json;
52
53 #[test]
54 fn accepts_valid_traceparent() {
55 let context = IpcTraceContext {
56 traceparent: Some(
57 "00-00112233445566778899aabbccddeeff-0123456789abcdef-01".to_string(),
58 ),
59 };
60
61 assert_eq!(
62 ipc_traceparent(Some(&context)),
63 "00-00112233445566778899aabbccddeeff-0123456789abcdef-01"
64 );
65 }
66
67 #[test]
68 fn ignores_invalid_traceparent() {
69 let context = IpcTraceContext {
70 traceparent: Some("not-a-traceparent".to_string()),
71 };
72
73 assert_eq!(ipc_traceparent(Some(&context)), "");
74 assert_eq!(ipc_traceparent(None), "");
75 }
76
77 #[test]
78 fn deserializes_missing_or_extra_fields_safely() {
79 let missing: IpcTraceContext = serde_json::from_value(json!({})).unwrap();
80 let extra: IpcTraceContext = serde_json::from_value(json!({
81 "traceparent": "00-00112233445566778899aabbccddeeff-0123456789abcdef-01",
82 "future": true
83 }))
84 .unwrap();
85
86 assert_eq!(ipc_traceparent(Some(&missing)), "");
87 assert_eq!(
88 ipc_traceparent(Some(&extra)),
89 "00-00112233445566778899aabbccddeeff-0123456789abcdef-01"
90 );
91 }
92}