glean_core/
common_metric_data.rs1use std::sync::atomic::{AtomicU8, Ordering};
6
7use crate::error::{Error, ErrorKind};
8use crate::metrics::labeled::validate_dynamic_label;
9use crate::Glean;
10use serde::{Deserialize, Serialize};
11
12#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
16#[repr(i32)] #[serde(rename_all = "lowercase")]
18pub enum Lifetime {
19 #[default]
21 Ping,
22 Application,
24 User,
26}
27
28impl Lifetime {
29 pub fn as_str(self) -> &'static str {
31 match self {
32 Lifetime::Ping => "ping",
33 Lifetime::Application => "app",
34 Lifetime::User => "user",
35 }
36 }
37}
38
39impl TryFrom<i32> for Lifetime {
40 type Error = Error;
41
42 fn try_from(value: i32) -> Result<Lifetime, Self::Error> {
43 match value {
44 0 => Ok(Lifetime::Ping),
45 1 => Ok(Lifetime::Application),
46 2 => Ok(Lifetime::User),
47 e => Err(ErrorKind::Lifetime(e).into()),
48 }
49 }
50}
51
52#[derive(Default, Debug, Clone, Deserialize, Serialize)]
54pub struct CommonMetricData {
55 pub name: String,
57 pub category: String,
59 pub send_in_pings: Vec<String>,
61 pub lifetime: Lifetime,
63 pub disabled: bool,
67 pub dynamic_label: Option<String>,
74}
75
76#[derive(Default, Debug)]
77pub struct CommonMetricDataInternal {
78 pub inner: CommonMetricData,
79 pub disabled: AtomicU8,
80}
81
82impl Clone for CommonMetricDataInternal {
83 fn clone(&self) -> Self {
84 Self {
85 inner: self.inner.clone(),
86 disabled: AtomicU8::new(self.disabled.load(Ordering::Relaxed)),
87 }
88 }
89}
90
91impl From<CommonMetricData> for CommonMetricDataInternal {
92 fn from(input_data: CommonMetricData) -> Self {
93 let disabled = input_data.disabled;
94 Self {
95 inner: input_data,
96 disabled: AtomicU8::new(u8::from(disabled)),
97 }
98 }
99}
100
101impl CommonMetricDataInternal {
102 pub fn new<A: Into<String>, B: Into<String>, C: Into<String>>(
104 category: A,
105 name: B,
106 ping_name: C,
107 ) -> CommonMetricDataInternal {
108 CommonMetricDataInternal {
109 inner: CommonMetricData {
110 name: name.into(),
111 category: category.into(),
112 send_in_pings: vec![ping_name.into()],
113 ..Default::default()
114 },
115 disabled: AtomicU8::new(0),
116 }
117 }
118
119 pub(crate) fn base_identifier(&self) -> String {
124 if self.inner.category.is_empty() {
125 self.inner.name.clone()
126 } else {
127 format!("{}.{}", self.inner.category, self.inner.name)
128 }
129 }
130
131 pub(crate) fn identifier(&self, glean: &Glean) -> String {
136 let base_identifier = self.base_identifier();
137
138 if let Some(label) = &self.inner.dynamic_label {
139 validate_dynamic_label(glean, self, &base_identifier, label)
140 } else {
141 base_identifier
142 }
143 }
144
145 pub fn storage_names(&self) -> &[String] {
147 &self.inner.send_in_pings
148 }
149}