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 uuid::Uuid; 6 7 use crate::error_recording::{record_error, ErrorType}; 8 use crate::metrics::Metric; 9 use crate::metrics::MetricType; 10 use crate::storage::StorageManager; 11 use crate::CommonMetricData; 12 use crate::Glean; 13 14 /// An UUID metric. 15 /// 16 /// Stores UUID v4 (randomly generated) values. 17 #[derive(Clone, Debug)] 18 pub struct UuidMetric { 19 meta: CommonMetricData, 20 } 21 22 impl MetricType for UuidMetric { meta(&self) -> &CommonMetricData23 fn meta(&self) -> &CommonMetricData { 24 &self.meta 25 } 26 meta_mut(&mut self) -> &mut CommonMetricData27 fn meta_mut(&mut self) -> &mut CommonMetricData { 28 &mut self.meta 29 } 30 } 31 32 // IMPORTANT: 33 // 34 // When changing this implementation, make sure all the operations are 35 // also declared in the related trait in `../traits/`. 36 impl UuidMetric { 37 /// Creates a new UUID metric new(meta: CommonMetricData) -> Self38 pub fn new(meta: CommonMetricData) -> Self { 39 Self { meta } 40 } 41 42 /// Sets to the specified value. 43 /// 44 /// # Arguments 45 /// 46 /// * `glean` - The Glean instance this metric belongs to. 47 /// * `value` - The [`Uuid`] to set the metric to. set(&self, glean: &Glean, value: Uuid)48 pub fn set(&self, glean: &Glean, value: Uuid) { 49 if !self.should_record(glean) { 50 return; 51 } 52 53 let s = value.to_string(); 54 let value = Metric::Uuid(s); 55 glean.storage().record(glean, &self.meta, &value) 56 } 57 58 /// Sets to the specified value, from a string. 59 /// 60 /// This should only be used from FFI. When calling directly from Rust, it 61 /// is better to use [`set`](UuidMetric::set). 62 /// 63 /// # Arguments 64 /// 65 /// * `glean` - The Glean instance this metric belongs to. 66 /// * `value` - The [`Uuid`] to set the metric to. set_from_str(&self, glean: &Glean, value: &str)67 pub fn set_from_str(&self, glean: &Glean, value: &str) { 68 if !self.should_record(glean) { 69 return; 70 } 71 72 if let Ok(uuid) = uuid::Uuid::parse_str(&value) { 73 self.set(glean, uuid); 74 } else { 75 let msg = format!("Unexpected UUID value '{}'", value); 76 record_error(glean, &self.meta, ErrorType::InvalidValue, msg, None); 77 } 78 } 79 80 /// Generates a new random [`Uuid`'] and sets the metric to it. 81 /// 82 /// # Arguments 83 /// 84 /// * `glean` - The Glean instance this metric belongs to. generate_and_set(&self, storage: &Glean) -> Uuid85 pub fn generate_and_set(&self, storage: &Glean) -> Uuid { 86 let uuid = Uuid::new_v4(); 87 self.set(storage, uuid); 88 uuid 89 } 90 91 /// Gets the stored Uuid value. 92 /// 93 /// # Arguments 94 /// 95 /// * `glean` - the Glean instance this metric belongs to. 96 /// * `storage_name` - the storage name to look into. 97 /// 98 /// # Returns 99 /// 100 /// The stored value or `None` if nothing stored. get_value(&self, glean: &Glean, storage_name: &str) -> Option<Uuid>101 pub(crate) fn get_value(&self, glean: &Glean, storage_name: &str) -> Option<Uuid> { 102 match StorageManager.snapshot_metric( 103 glean.storage(), 104 storage_name, 105 &self.meta().identifier(glean), 106 self.meta.lifetime, 107 ) { 108 Some(Metric::Uuid(uuid)) => Uuid::parse_str(&uuid).ok(), 109 _ => None, 110 } 111 } 112 113 /// **Test-only API (exported for FFI purposes).** 114 /// 115 /// Gets the currently stored value as a string. 116 /// 117 /// This doesn't clear the stored value. test_get_value(&self, glean: &Glean, storage_name: &str) -> Option<Uuid>118 pub fn test_get_value(&self, glean: &Glean, storage_name: &str) -> Option<Uuid> { 119 self.get_value(glean, storage_name) 120 } 121 } 122