[client-libraries] Add rust client library
This is an improved copy of the traits.rs file from fuchsia.
Bug: 42930
Change-Id: I321fa07c2f5f9c6690852c52168cf1e920567b30
diff --git a/cobaltb.py b/cobaltb.py
index b38b30e..834c05d 100755
--- a/cobaltb.py
+++ b/cobaltb.py
@@ -289,7 +289,7 @@
# it represents. Note that 'cloud_bt' and 'perf' tests are special. They are
# not included in 'all'. They are only run if asked for explicitly.
FILTER_MAP = {
- 'all': ['cpp', 'go', 'other'],
+ 'all': ['cpp', 'go', 'other', 'rust'],
'cpp': ['cpp'],
'go': ['go'],
'perf': ['perf'],
diff --git a/src/lib/BUILD.gn b/src/lib/BUILD.gn
index c9bca95..082dd03 100644
--- a/src/lib/BUILD.gn
+++ b/src/lib/BUILD.gn
@@ -6,6 +6,7 @@
testonly = true
deps = [
"clearcut:tests",
+ "client:tests",
"crypto_util:tests",
"util:tests",
]
diff --git a/src/lib/client/BUILD.gn b/src/lib/client/BUILD.gn
new file mode 100644
index 0000000..55a5a0c
--- /dev/null
+++ b/src/lib/client/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+group("tests") {
+ testonly = true
+ deps = [
+ "rust:tests",
+ ]
+}
diff --git a/src/lib/client/rust/BUILD.gn b/src/lib/client/rust/BUILD.gn
new file mode 100644
index 0000000..db7c7e8
--- /dev/null
+++ b/src/lib/client/rust/BUILD.gn
@@ -0,0 +1,16 @@
+import("//build/rust/rustc_library.gni")
+
+rustc_library("cobalt-client") {
+ name = "cobalt_client"
+ edition = "2018"
+ version = "0.1.0"
+
+ with_unit_tests = true
+}
+
+group("tests") {
+ testonly = true
+ deps = [
+ ":cobalt-client_test_build",
+ ]
+}
diff --git a/src/lib/client/rust/src/lib.rs b/src/lib/client/rust/src/lib.rs
new file mode 100644
index 0000000..fcaa8c7
--- /dev/null
+++ b/src/lib/client/rust/src/lib.rs
@@ -0,0 +1,9 @@
+// Copyright 2019 Zachary Bush.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod traits;
diff --git a/src/lib/client/rust/src/traits.rs b/src/lib/client/rust/src/traits.rs
new file mode 100644
index 0000000..d41a990
--- /dev/null
+++ b/src/lib/client/rust/src/traits.rs
@@ -0,0 +1,137 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Traits for use with the rust client library for cobalt.
+
+/// `AsEventCode` is any type that can be converted into a `u32` for the purposes of reporting to
+/// cobalt.
+pub trait AsEventCode {
+ fn as_event_code(&self) -> u32;
+}
+
+impl AsEventCode for u32 {
+ fn as_event_code(&self) -> u32 {
+ *self
+ }
+}
+
+/// `AsEventCodes` is any type that can be converted into a `Vec<u32>` for the purposes of reporting
+/// to cobalt.
+pub trait AsEventCodes {
+ /// Converts the source type into a `Vec<u32>` of event codes.
+ fn as_event_codes(&self) -> Vec<u32>;
+}
+
+impl AsEventCodes for () {
+ fn as_event_codes(&self) -> Vec<u32> {
+ Vec::new()
+ }
+}
+
+impl<A: AsEventCode> AsEventCodes for A {
+ fn as_event_codes(&self) -> Vec<u32> {
+ vec![self.as_event_code()]
+ }
+}
+
+impl<A: AsEventCode> AsEventCodes for Vec<A> {
+ fn as_event_codes(&self) -> Vec<u32> {
+ self.iter().map(AsEventCode::as_event_code).collect()
+ }
+}
+
+impl<A: AsEventCode> AsEventCodes for [A] {
+ fn as_event_codes(&self) -> Vec<u32> {
+ self.iter().map(AsEventCode::as_event_code).collect()
+ }
+}
+
+macro_rules! array_impls {
+ ($($N:expr)+) => {
+ $(
+ impl<A: AsEventCode> AsEventCodes for [A; $N] {
+ fn as_event_codes(&self) -> Vec<u32> {
+ self[..].as_event_codes()
+ }
+ }
+ )+
+ }
+}
+
+array_impls! {0 1 2 3 4 5 6}
+
+macro_rules! tuple_impls {
+ ($(($($N:ident => $i:tt),*)),*) => {
+ $(
+ impl <$($N: AsEventCode),*> AsEventCodes for ($($N),*,) {
+ fn as_event_codes(&self) -> Vec<u32> {
+ vec![$(
+ self.$i.as_event_code()
+ ),*]
+ }
+ }
+ )*
+ }
+}
+
+tuple_impls! {
+ (A => 0),
+ (A => 0, B => 1),
+ (A => 0, B => 1, C => 2),
+ (A => 0, B => 1, C => 2, D => 3),
+ (A => 0, B => 1, C => 2, D => 3, E => 4),
+ (A => 0, B => 1, C => 2, D => 3, E => 4, F => 5)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[derive(Clone, Copy)]
+ enum EventCode1 {
+ A = 1,
+ B = 2,
+ }
+
+ impl AsEventCode for EventCode1 {
+ fn as_event_code(&self) -> u32 {
+ *self as u32
+ }
+ }
+
+ #[derive(Clone, Copy)]
+ enum EventCode2 {
+ C = 3,
+ D = 4,
+ }
+
+ impl AsEventCode for EventCode2 {
+ fn as_event_code(&self) -> u32 {
+ *self as u32
+ }
+ }
+
+ #[test]
+ fn test_as_event_codes() {
+ assert_eq!(().as_event_codes(), vec![]);
+ assert_eq!(([] as [u32; 0]).as_event_codes(), vec![]);
+ assert_eq!(1.as_event_codes(), vec![1]);
+ assert_eq!([1].as_event_codes(), vec![1]);
+ assert_eq!(vec![1].as_event_codes(), vec![1]);
+ assert_eq!([1, 2].as_event_codes(), vec![1, 2]);
+ assert_eq!(vec![1, 2].as_event_codes(), vec![1, 2]);
+ assert_eq!([1, 2, 3].as_event_codes(), vec![1, 2, 3]);
+ assert_eq!(vec![1, 2, 3].as_event_codes(), vec![1, 2, 3]);
+ assert_eq!([1, 2, 3, 4].as_event_codes(), vec![1, 2, 3, 4]);
+ assert_eq!(vec![1, 2, 3, 4].as_event_codes(), vec![1, 2, 3, 4]);
+ assert_eq!([1, 2, 3, 4, 5].as_event_codes(), vec![1, 2, 3, 4, 5]);
+ assert_eq!(vec![1, 2, 3, 4, 5].as_event_codes(), vec![1, 2, 3, 4, 5]);
+
+ assert_eq!((EventCode1::A, EventCode2::C).as_event_codes(), vec![1, 3]);
+ assert_eq!(
+ (0, EventCode1::B, 10, EventCode2::D).as_event_codes(),
+ vec![0, 2, 10, 4]
+ );
+ }
+}