1 // This Source Code Form is subject to the terms of the Mozilla Public
2 // License, v. 2.0. If a copy of the MPL was not distributed with this
3 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4 
5 use inherent::inherent;
6 use std::sync::Arc;
7 
8 use glean_core::metrics::MetricType;
9 use glean_core::ErrorType;
10 
11 // We need to wrap the glean-core type: otherwise if we try to implement
12 // the trait for the metric in `glean_core::metrics` we hit error[E0117]:
13 // only traits defined in the current crate can be implemented for arbitrary
14 // types.
15 
16 /// Developer-facing API for recording string list metrics.
17 ///
18 /// Instances of this class type are automatically generated by the parsers
19 /// at build time, allowing developers to record values that were previously
20 /// registered in the metrics.yaml file.
21 #[derive(Clone)]
22 pub struct StringListMetric(pub(crate) Arc<glean_core::metrics::StringListMetric>);
23 
24 impl StringListMetric {
25     /// The public constructor used by automatically generated metrics.
new(meta: glean_core::CommonMetricData) -> Self26     pub fn new(meta: glean_core::CommonMetricData) -> Self {
27         Self(Arc::new(glean_core::metrics::StringListMetric::new(meta)))
28     }
29 }
30 
31 #[inherent(pub)]
32 impl glean_core::traits::StringList for StringListMetric {
add<S: Into<String>>(&self, value: S)33     fn add<S: Into<String>>(&self, value: S) {
34         let metric = Arc::clone(&self.0);
35         let new_value = value.into();
36         crate::launch_with_glean(move |glean| metric.add(glean, new_value));
37     }
38 
set(&self, value: Vec<String>)39     fn set(&self, value: Vec<String>) {
40         let metric = Arc::clone(&self.0);
41         crate::launch_with_glean(move |glean| metric.set(glean, value));
42     }
43 
test_get_value<'a, S: Into<Option<&'a str>>>(&self, ping_name: S) -> Option<Vec<String>>44     fn test_get_value<'a, S: Into<Option<&'a str>>>(&self, ping_name: S) -> Option<Vec<String>> {
45         crate::block_on_dispatcher();
46 
47         let queried_ping_name = ping_name
48             .into()
49             .unwrap_or_else(|| &self.0.meta().send_in_pings[0]);
50 
51         crate::with_glean(|glean| self.0.test_get_value(glean, queried_ping_name))
52     }
53 
test_get_num_recorded_errors<'a, S: Into<Option<&'a str>>>( &self, error: ErrorType, ping_name: S, ) -> i3254     fn test_get_num_recorded_errors<'a, S: Into<Option<&'a str>>>(
55         &self,
56         error: ErrorType,
57         ping_name: S,
58     ) -> i32 {
59         crate::block_on_dispatcher();
60 
61         crate::with_glean_mut(|glean| {
62             glean_core::test_get_num_recorded_errors(&glean, self.0.meta(), error, ping_name.into())
63                 .unwrap_or(0)
64         })
65     }
66 }
67 
68 #[cfg(test)]
69 mod test {
70     use super::*;
71     use crate::common_test::{lock_test, new_glean};
72     use crate::{CommonMetricData, ErrorType};
73 
74     #[test]
string_list_metric_docs()75     fn string_list_metric_docs() {
76         let _lock = lock_test();
77         let _t = new_glean(None, true);
78 
79         let engine_metric: StringListMetric = StringListMetric::new(CommonMetricData {
80             name: "event".into(),
81             category: "test".into(),
82             send_in_pings: vec!["test1".into()],
83             ..Default::default()
84         });
85 
86         let engines: Vec<String> = vec!["Google".to_string(), "DuckDuckGo".to_string()];
87 
88         // Add them one at a time
89         engines.iter().for_each(|x| engine_metric.add(x));
90 
91         // Set them in one go
92         engine_metric.set(engines);
93 
94         assert!(engine_metric.test_get_value(None).is_some());
95 
96         assert_eq!(
97             vec!["Google".to_string(), "DuckDuckGo".to_string()],
98             engine_metric.test_get_value(None).unwrap()
99         );
100 
101         assert_eq!(
102             0,
103             engine_metric.test_get_num_recorded_errors(ErrorType::InvalidValue, None)
104         );
105     }
106 }
107