glean_core/traits/
event.rs

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
5use std::collections::HashMap;
6use std::hash::Hash;
7
8use crate::event_database::RecordedEvent;
9use crate::{ErrorType, TestGetValue};
10
11/// Extra keys for events.
12///
13/// Extra keys need to be pre-defined and map to a string representation.
14///
15/// For user-defined `EventMetric`s these will be defined as `struct`s.
16/// Each extra key will be a field in that struct.
17/// Each field will correspond to an entry in the `ALLOWED_KEYS` list.
18/// The Glean SDK requires the keys as strings for submission in pings,
19/// whereas in code we want to provide users a type to work with
20/// (e.g. to avoid typos or misuse of the API).
21pub trait ExtraKeys {
22    /// List of allowed extra keys as strings.
23    const ALLOWED_KEYS: &'static [&'static str];
24
25    /// Convert the event extras into 2 lists:
26    ///
27    /// 1. The list of extra key indices.
28    ///    Unset keys will be skipped.
29    /// 2. The list of extra values.
30    fn into_ffi_extra(self) -> HashMap<String, String>;
31}
32
33/// Default of no extra keys for events.
34///
35/// An enum with no values for convenient use as the default set of extra keys
36/// that an [`EventMetric`](crate::metrics::EventMetric) can accept.
37///
38/// *Note*: There exist no values for this enum, it can never exist.
39/// It its equivalent to the [`never / !` type](https://doc.rust-lang.org/std/primitive.never.html).
40#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
41pub enum NoExtraKeys {}
42
43impl ExtraKeys for NoExtraKeys {
44    const ALLOWED_KEYS: &'static [&'static str] = &[];
45
46    fn into_ffi_extra(self) -> HashMap<String, String> {
47        unimplemented!("non-existing extra keys can't be turned into a list")
48    }
49}
50
51/// The possible errors when parsing to an extra key.
52pub enum EventRecordingError {
53    /// The id doesn't correspond to a valid extra key
54    InvalidId,
55    /// The value doesn't correspond to a valid extra key
56    InvalidExtraKey,
57}
58
59impl TryFrom<i32> for NoExtraKeys {
60    type Error = EventRecordingError;
61
62    fn try_from(_value: i32) -> Result<Self, Self::Error> {
63        Err(EventRecordingError::InvalidExtraKey)
64    }
65}
66
67impl TryFrom<&str> for NoExtraKeys {
68    type Error = EventRecordingError;
69
70    fn try_from(_value: &str) -> Result<Self, Self::Error> {
71        Err(EventRecordingError::InvalidExtraKey)
72    }
73}
74
75/// A description for the [`EventMetric`](crate::metrics::EventMetric) type.
76///
77/// When changing this trait, make sure all the operations are
78/// implemented in the related type in `../metrics/`.
79pub trait Event: TestGetValue<Vec<RecordedEvent>> {
80    /// The type of the allowed extra keys for this event.
81    type Extra: ExtraKeys;
82
83    /// Records an event.
84    ///
85    /// # Arguments
86    ///
87    /// * `extra` - (optional) An object for the extra keys.
88    fn record<M: Into<Option<Self::Extra>>>(&self, extra: M);
89
90    /// **Exported for test purposes.**
91    ///
92    /// Gets the number of recorded errors for the given metric and error type.
93    ///
94    /// # Arguments
95    ///
96    /// * `error` - The type of error
97    ///
98    /// # Returns
99    ///
100    /// The number of errors reported.
101    fn test_get_num_recorded_errors(&self, error: ErrorType) -> i32;
102}