cobalt_client/
traits.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Traits for use with the rust client library for cobalt.
6
7/// `AsEventCode` is any type that can be converted into a `u32` for the purposes of reporting to
8/// cobalt.
9pub trait AsEventCode {
10    fn as_event_code(&self) -> u32;
11}
12
13macro_rules! int_impls {
14    ($($I:ident)+) => {
15        $(
16            impl AsEventCode for $I {
17                fn as_event_code(&self) -> u32 {
18                    *self as u32
19                }
20            }
21        )+
22    };
23}
24
25int_impls!(u32 u16 u8 i32 i16 i8);
26
27/// `AsEventCodes` is any type that can be converted into a `Vec<u32>` for the purposes of reporting
28/// to cobalt.
29pub trait AsEventCodes {
30    /// Converts the source type into a `Vec<u32>` of event codes.
31    fn as_event_codes(&self) -> Vec<u32>;
32}
33
34impl AsEventCodes for () {
35    fn as_event_codes(&self) -> Vec<u32> {
36        Vec::new()
37    }
38}
39
40impl<A: AsEventCode> AsEventCodes for A {
41    fn as_event_codes(&self) -> Vec<u32> {
42        vec![self.as_event_code()]
43    }
44}
45
46impl<A: AsEventCode> AsEventCodes for Vec<A> {
47    fn as_event_codes(&self) -> Vec<u32> {
48        self.iter().map(AsEventCode::as_event_code).collect()
49    }
50}
51
52impl<A: AsEventCode> AsEventCodes for [A] {
53    fn as_event_codes(&self) -> Vec<u32> {
54        self.iter().map(AsEventCode::as_event_code).collect()
55    }
56}
57
58macro_rules! array_impls {
59    ($($N:expr)+) => {
60        $(
61            impl<A: AsEventCode> AsEventCodes for [A; $N] {
62                fn as_event_codes(&self) -> Vec<u32> {
63                    self[..].as_event_codes()
64                }
65            }
66        )+
67    }
68}
69
70array_impls! {0 1 2 3 4 5 6}
71
72macro_rules! tuple_impls {
73    ($(($($N:ident => $i:tt),*)),*) => {
74        $(
75            impl <$($N: AsEventCode),*> AsEventCodes for ($($N),*,) {
76                fn as_event_codes(&self) -> Vec<u32> {
77                    vec![$(
78                        self.$i.as_event_code()
79                    ),*]
80                }
81            }
82        )*
83    }
84}
85
86tuple_impls! {
87    (A => 0),
88    (A => 0, B => 1),
89    (A => 0, B => 1, C => 2),
90    (A => 0, B => 1, C => 2, D => 3),
91    (A => 0, B => 1, C => 2, D => 3, E => 4),
92    (A => 0, B => 1, C => 2, D => 3, E => 4, F => 5)
93}
94
95#[cfg(test)]
96mod tests {
97    use super::*;
98
99    #[derive(Clone, Copy)]
100    enum EventCode1 {
101        A = 1,
102        B = 2,
103    }
104
105    impl AsEventCode for EventCode1 {
106        fn as_event_code(&self) -> u32 {
107            *self as u32
108        }
109    }
110
111    #[derive(Clone, Copy)]
112    enum EventCode2 {
113        C = 3,
114        D = 4,
115    }
116
117    impl AsEventCode for EventCode2 {
118        fn as_event_code(&self) -> u32 {
119            *self as u32
120        }
121    }
122
123    #[test]
124    fn test_as_event_codes() {
125        assert_eq!(().as_event_codes(), vec![]);
126        assert_eq!(([] as [u32; 0]).as_event_codes(), vec![]);
127        assert_eq!(1.as_event_codes(), vec![1]);
128        assert_eq!([1].as_event_codes(), vec![1]);
129        assert_eq!(vec![1].as_event_codes(), vec![1]);
130        assert_eq!([1, 2].as_event_codes(), vec![1, 2]);
131        assert_eq!(vec![1, 2].as_event_codes(), vec![1, 2]);
132        assert_eq!([1, 2, 3].as_event_codes(), vec![1, 2, 3]);
133        assert_eq!(vec![1, 2, 3].as_event_codes(), vec![1, 2, 3]);
134        assert_eq!([1, 2, 3, 4].as_event_codes(), vec![1, 2, 3, 4]);
135        assert_eq!(vec![1, 2, 3, 4].as_event_codes(), vec![1, 2, 3, 4]);
136        assert_eq!([1, 2, 3, 4, 5].as_event_codes(), vec![1, 2, 3, 4, 5]);
137        assert_eq!(vec![1, 2, 3, 4, 5].as_event_codes(), vec![1, 2, 3, 4, 5]);
138
139        assert_eq!((EventCode1::A, EventCode2::C).as_event_codes(), vec![1, 3]);
140        assert_eq!((0, EventCode1::B, 10, EventCode2::D).as_event_codes(), vec![0, 2, 10, 4]);
141    }
142}