// -*- mode: Rust -*- // AUTOGENERATED BY glean_parser. DO NOT EDIT. {# The rendered source is autogenerated, but this Jinja2 template is not. Please file bugs! #} /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ {% macro generate_extra_keys(obj) -%} {% for name, _ in obj["_generate_enums"] %} {# we always use the `extra` suffix, because we only expose the new event API #} {% set suffix = "Extra" %} {% if obj|attr(name)|length %} {{ extra_keys_with_types(obj, name, suffix)|indent }} {% endif %} {% endfor %} {%- endmacro -%} {%- macro extra_keys_with_types(obj, name, suffix) -%} #[derive(Default, Debug, Clone, Hash, Eq, PartialEq)] pub struct {{ obj.name|Camelize }}{{ suffix }} { {% for item, type in obj|attr(name) %} pub {{ item|snake_case }}: Option<{{type|extra_type_name}}>, {% endfor %} } impl ExtraKeys for {{ obj.name|Camelize }}{{ suffix }} { const ALLOWED_KEYS: &'static [&'static str] = {{ obj.allowed_extra_keys|extra_keys }}; fn into_ffi_extra(self) -> ::std::collections::HashMap { let mut map = ::std::collections::HashMap::new(); {% for key, _ in obj|attr(name) %} self.{{key|snake_case}}.and_then(|val| map.insert("{{key|snake_case}}".into(), val.to_string())); {% endfor %} map } } {%- endmacro -%} {% macro generate_label_enum(obj) %} #[repr(u16)] pub enum {{ obj.name|Camelize }}Label { {% for label in obj.ordered_labels %} {# Specifically _not_ using r# as C++ doesn't have it #} {{ label|Camelize }} = {{loop.index0}}, {% endfor %} __Other__, } impl From for {{ obj.name|Camelize }}Label { fn from(v: u16) -> Self { match v { {% for label in obj.ordered_labels %} {{ loop.index0 }} => Self::{{ label|Camelize }}, {% endfor %} _ => Self::__Other__, } } } impl Into<&'static str> for {{ obj.name|Camelize }}Label { fn into(self) -> &'static str { match self { {% for label in obj.ordered_labels %} Self::{{ label| Camelize }} => "{{label}}", {% endfor %} Self::__Other__ => "__other__", } } } {%- endmacro -%} pub enum DynamicLabel { } {% for category_name, objs in all_objs.items() %} pub mod {{ category_name|snake_case }} { use crate::private::*; #[allow(unused_imports)] // CommonMetricData might be unused, let's avoid warnings use glean::CommonMetricData; #[allow(unused_imports)] // HistogramType might be unusued, let's avoid warnings use glean::HistogramType; use once_cell::sync::Lazy; {% for obj in objs.values() %} {% if obj|attr("_generate_enums") %} {{ generate_extra_keys(obj) }} {%- endif %} {% if obj.labeled and obj.labels and obj.labels|length %} {{ generate_label_enum(obj)|indent }} {% endif %} #[allow(non_upper_case_globals)] /// generated from {{ category_name }}.{{ obj.name }} /// /// {{ obj.description|wordwrap() | replace('\n', '\n /// ') }} {% if obj.type == "counter" and obj.send_in_pings|length == 1 and not obj.disabled and obj.lifetime|rust == "Lifetime::Ping" %} {# Use optimized CounterMetric ctor in a common case (esp. for Use Counters) #} pub static {{ obj.name|snake_case }}: Lazy<{{ obj|type_name }}> = Lazy::new(|| { CounterMetric::codegen_new( {{obj|metric_id}}, "{{obj.category}}", "{{obj.name}}", "{{obj.send_in_pings[0]}}" ) }); {% else %} pub static {{ obj.name|snake_case }}: Lazy<{{ obj|type_name }}> = Lazy::new(|| { {{ obj|ctor }}({{obj|metric_id}}.into(), CommonMetricData { {% for arg_name in common_metric_data_args if obj[arg_name] is defined %} {{ arg_name }}: {{ obj[arg_name]|rust }}, {% endfor %} ..Default::default() } {%- for arg_name in extra_args if obj[arg_name] is defined and arg_name not in common_metric_data_args and arg_name != 'allowed_extra_keys' -%} , {{ obj[arg_name]|rust }} {%- endfor -%} {{ ", " if obj.labeled else ")\n" }} {%- if obj.labeled -%} {%- if obj.labels -%} Some({{ obj.labels|rust }}) {%- else -%} None {%- endif -%}) {% endif %} }); {% endif %} {% endfor %} } {% endfor %} {% if metric_by_type|length > 0 %} #[allow(dead_code)] pub(crate) mod __glean_metric_maps { use std::collections::HashMap; use crate::metrics::extra_keys_len; use crate::private::*; use once_cell::sync::Lazy; {% for typ, metrics in metric_by_type.items() %} pub static {{typ.0}}: Lazy>> = Lazy::new(|| { let mut map = HashMap::with_capacity({{metrics|length}}); {% for metric in metrics %} map.insert({{metric.0}}.into(), &super::{{metric.1}}); {% endfor %} map }); {% endfor %} /// Wrapper to record an event based on its metric ID. /// /// # Arguments /// /// * `metric_id` - The metric's ID to look up /// * `extra` - An map of (extra key id, string) pairs. /// The map will be decoded into the appropriate `ExtraKeys` type. /// # Returns /// /// Returns `Ok(())` if the event was found and `record` was called with the given `extra`, /// or an `EventRecordingError::InvalidId` if no event by that ID exists /// or an `EventRecordingError::InvalidExtraKey` if the `extra` map could not be deserialized. pub(crate) fn record_event_by_id(metric_id: u32, extra: HashMap) -> Result<(), EventRecordingError> { match metric_id { {% for metric_id, event in events_by_id.items() %} {{metric_id}} => { assert!( extra_keys_len(&super::{{event}}) != 0 || extra.is_empty(), "No extra keys allowed, but some were passed" ); super::{{event}}.record_raw(extra); Ok(()) } {% endfor %} _ => Err(EventRecordingError::InvalidId), } } /// Wrapper to record an event based on its metric ID, with a provided timestamp. /// /// # Arguments /// /// * `metric_id` - The metric's ID to look up /// * `timestamp` - The time at which this event was recorded. /// * `extra` - An map of (extra key id, string) pairs. /// The map will be decoded into the appropriate `ExtraKeys` type. /// # Returns /// /// Returns `Ok(())` if the event was found and `record` was called with the given `extra`, /// or an `EventRecordingError::InvalidId` if no event by that ID exists /// or an `EventRecordingError::InvalidExtraKey` if the event doesn't take extra pairs, /// but some are passed in. pub(crate) fn record_event_by_id_with_time(metric_id: MetricId, timestamp: u64, extra: HashMap) -> Result<(), EventRecordingError> { match metric_id { {% for metric_id, event in events_by_id.items() %} MetricId({{metric_id}}) => { if extra_keys_len(&super::{{event}}) == 0 && !extra.is_empty() { return Err(EventRecordingError::InvalidExtraKey); } super::{{event}}.record_with_time(timestamp, extra); Ok(()) } {% endfor %} _ => Err(EventRecordingError::InvalidId), } } /// Wrapper to get the currently stored events for event metric. /// /// # Arguments /// /// * `metric_id` - The metric's ID to look up /// * `ping_name` - (Optional) The ping name to look into. /// Defaults to the first value in `send_in_pings`. /// /// # Returns /// /// Returns the recorded events or `None` if nothing stored. /// /// # Panics /// /// Panics if no event by the given metric ID could be found. pub(crate) fn event_test_get_value_wrapper(metric_id: u32, ping_name: Option) -> Option> { match metric_id { {% for metric_id, event in events_by_id.items() %} {{metric_id}} => super::{{event}}.test_get_value(ping_name.as_deref()), {% endfor %} _ => panic!("No event for metric id {}", metric_id), } } /// Check the provided event for errors. /// /// # Arguments /// /// * `metric_id` - The metric's ID to look up /// * `ping_name` - (Optional) The ping name to look into. /// Defaults to the first value in `send_in_pings`. /// /// # Returns /// /// Returns a string for the recorded error or `None`. /// /// # Panics /// /// Panics if no event by the given metric ID could be found. #[allow(unused_variables)] pub(crate) fn event_test_get_error(metric_id: u32) -> Option { #[cfg(feature = "with_gecko")] match metric_id { {% for metric_id, event in events_by_id.items() %} {{metric_id}} => test_get_errors!(super::{{event}}), {% endfor %} _ => panic!("No event for metric id {}", metric_id), } #[cfg(not(feature = "with_gecko"))] { return None; } } {% for labeled_type, labeleds_by_id in labeleds_by_id_by_type.items() %} /// Gets the submetric from the specified labeled_{{labeled_type}} metric. /// /// # Arguments /// /// * `metric_id` - The metric's ID to look up /// * `label` - The label identifying the {{labeled_type}} submetric. /// /// # Returns /// /// Returns the {{labeled_type}} submetric. /// /// # Panics /// /// Panics if no labeled_{{labeled_type}} by the given metric ID could be found. #[allow(unused_variables)] pub(crate) fn labeled_{{labeled_type}}_get(metric_id: u32, label: &str) -> Labeled{{labeled_type|Camelize}}Metric { match metric_id { {% for metric_id, (labeled, _) in labeleds_by_id.items() %} {{metric_id}} => super::{{labeled}}.get(label), {% endfor %} _ => panic!("No labeled_{{labeled_type}} for metric id {}", metric_id), } } /// Gets the submetric from the specified labeled_{{labeled_type}} metric, by enum. /// /// # Arguments /// /// * `metric_id` - The metric's ID to look up /// * `label_enum` - The label enum identifying the {{labeled_type}} submetric. /// /// # Returns /// /// Returns the {{labeled_type}} submetric. /// /// # Panics /// /// Panics if no labeled_{{labeled_type}} by the given metric ID could be found. #[allow(unused_variables)] pub(crate) fn labeled_{{labeled_type}}_enum_get(metric_id: u32, label_enum: u16) -> Labeled{{labeled_type|Camelize}}Metric { match metric_id { {% for metric_id, (labeled, has_enum) in labeleds_by_id.items() %} {% if has_enum %} {{metric_id}} => super::{{labeled}}.get(labeled_enum_to_str(metric_id, label_enum)), {% endif %} {% endfor %} _ => panic!("No labeled_{{labeled_type}} for metric id {}", metric_id), } } {% endfor %} pub(crate) fn labeled_enum_to_str(metric_id: u32, label: u16) -> &'static str { match metric_id { {% for category_name, objs in all_objs.items() %} {% for obj in objs.values() %} {% if obj.labeled and obj.labels and obj.labels|length %} {{obj|metric_id}} => super::{{category_name|snake_case}}::{{obj.name|Camelize}}Label::from(label).into(), {% endif %} {% endfor %} {% endfor %} _ => panic!("Can't turn label enum to string for metric {} which isn't a labeled metric with static labels", metric_id), } } pub(crate) mod submetric_maps { use std::sync::{ atomic::AtomicU32, RwLock, }; use super::*; pub(crate) const SUBMETRIC_BIT: u32 = {{submetric_bit}}; pub(crate) static NEXT_LABELED_SUBMETRIC_ID: AtomicU32 = AtomicU32::new((1 << SUBMETRIC_BIT) + 1); pub(crate) static LABELED_METRICS_TO_IDS: Lazy>> = Lazy::new(|| RwLock::new(HashMap::new()) ); pub(crate) static LABELED_ENUMS_TO_IDS: Lazy>> = Lazy::new(|| RwLock::new(HashMap::new()) ); {% for typ, metrics in metric_by_type.items() %} {% if typ.0 in ('BOOLEAN_MAP', 'COUNTER_MAP', 'STRING_MAP') %} pub static {{typ.0}}: Lazy>> = Lazy::new(|| RwLock::new(HashMap::new()) ); {% endif %} {% endfor%} } } {% endif %}