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