azure_core/policies/
telemetry_policy.rs
1use crate::headers::{HeaderValue, USER_AGENT};
2use crate::options::TelemetryOptions;
3use crate::policies::{Policy, PolicyResult};
4use crate::{Context, Request};
5use std::env::consts::{ARCH, OS};
6use std::sync::Arc;
7
8#[derive(Clone, Debug)]
9pub struct TelemetryPolicy {
10 header: String,
11}
12
13impl<'a> TelemetryPolicy {
15 pub fn new(
16 crate_name: Option<&'a str>,
17 crate_version: Option<&'a str>,
18 options: &TelemetryOptions,
19 ) -> Self {
20 Self::new_with_rustc_version(
21 crate_name,
22 crate_version,
23 option_env!("AZSDK_RUSTC_VERSION"),
24 options,
25 )
26 }
27
28 fn new_with_rustc_version(
29 crate_name: Option<&'a str>,
30 crate_version: Option<&'a str>,
31 rustc_version: Option<&'a str>,
32 options: &TelemetryOptions,
33 ) -> Self {
34 const UNKNOWN: &str = "unknown";
35 let mut crate_name = crate_name.unwrap_or(UNKNOWN);
36 let crate_version = crate_version.unwrap_or(UNKNOWN);
37 let rustc_version = rustc_version.unwrap_or(UNKNOWN);
38 let platform_info = format!("({rustc_version}; {OS}; {ARCH})",);
39
40 if let Some(name) = crate_name.strip_prefix("azure_") {
41 crate_name = name;
42 }
43
44 let header = match &options.application_id {
45 Some(application_id) => {
46 format!("{application_id} azsdk-rust-{crate_name}/{crate_version} {platform_info}")
47 }
48 None => format!("azsdk-rust-{crate_name}/{crate_version} {platform_info}"),
49 };
50
51 TelemetryPolicy { header }
52 }
53}
54
55#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
56#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
57impl Policy for TelemetryPolicy {
58 async fn send(
59 &self,
60 ctx: &Context,
61 request: &mut Request,
62 next: &[Arc<dyn Policy>],
63 ) -> PolicyResult {
64 request.insert_header(USER_AGENT, HeaderValue::from(self.header.to_string()));
65
66 next[0].send(ctx, request, &next[1..]).await
67 }
68}
69
70#[cfg(test)]
71mod test {
72 use super::*;
73
74 #[test]
75 fn test_without_application_id() {
76 let policy = TelemetryPolicy::new_with_rustc_version(
77 Some("azure_test"), Some("1.2.3"),
79 Some("4.5.6"),
80 &TelemetryOptions::default(),
81 );
82 assert_eq!(
83 policy.header,
84 format!("azsdk-rust-test/1.2.3 (4.5.6; {OS}; {ARCH})")
85 );
86 }
87
88 #[test]
89 fn test_with_application_id() {
90 let options = TelemetryOptions {
91 application_id: Some("my_app".to_string()),
92 };
93 let policy = TelemetryPolicy::new_with_rustc_version(
94 Some("test"),
95 Some("1.2.3"),
96 Some("4.5.6"),
97 &options,
98 );
99 assert_eq!(
100 policy.header,
101 format!("my_app azsdk-rust-test/1.2.3 (4.5.6; {OS}; {ARCH})")
102 );
103 }
104
105 #[test]
106 fn test_missing_env() {
107 let policy =
109 TelemetryPolicy::new_with_rustc_version(None, None, None, &TelemetryOptions::default());
110 assert_eq!(
111 policy.header,
112 format!("azsdk-rust-unknown/unknown (unknown; {OS}; {ARCH})")
113 );
114 }
115}