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::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 a hashmap of extra key to extra value.
26 fn into_ffi_extra(self) -> HashMap<String, String>;
27}
28
29/// Default of no extra keys for events.
30///
31/// An enum with no values for convenient use as the default set of extra keys
32/// that an [`EventMetric`](crate::metrics::EventMetric) can accept.
33///
34/// *Note*: There exist no values for this enum, it can never exist.
35/// It its equivalent to the [`never / !` type](https://doc.rust-lang.org/std/primitive.never.html).
36#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
37pub enum NoExtraKeys {}
38
39impl ExtraKeys for NoExtraKeys {
40 const ALLOWED_KEYS: &'static [&'static str] = &[];
41
42 fn into_ffi_extra(self) -> HashMap<String, String> {
43 unimplemented!("non-existing extra keys can't be turned into a list")
44 }
45}
46
47/// The possible errors when parsing to an extra key.
48pub enum EventRecordingError {
49 /// The id doesn't correspond to a valid extra key
50 InvalidId,
51 /// The value doesn't correspond to a valid extra key
52 InvalidExtraKey,
53}
54
55impl TryFrom<i32> for NoExtraKeys {
56 type Error = EventRecordingError;
57
58 fn try_from(_value: i32) -> Result<Self, Self::Error> {
59 Err(EventRecordingError::InvalidExtraKey)
60 }
61}
62
63impl TryFrom<&str> for NoExtraKeys {
64 type Error = EventRecordingError;
65
66 fn try_from(_value: &str) -> Result<Self, Self::Error> {
67 Err(EventRecordingError::InvalidExtraKey)
68 }
69}
70
71/// A description for the [`EventMetric`](crate::metrics::EventMetric) type.
72///
73/// When changing this trait, make sure all the operations are
74/// implemented in the related type in `../metrics/`.
75pub trait Event: TestGetValue<Output = Vec<RecordedEvent>> {
76 /// The type of the allowed extra keys for this event.
77 type Extra: ExtraKeys;
78
79 /// Records an event.
80 ///
81 /// # Arguments
82 ///
83 /// * `extra` - (optional) An object for the extra keys.
84 fn record<M: Into<Option<Self::Extra>>>(&self, extra: M);
85}