Squashed 'third_party/rules_rust/' content from commit bf59038ca
git-subtree-dir: third_party/rules_rust
git-subtree-split: bf59038cac11798cbaef9f3bf965bad8182b97fa
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
Change-Id: I5a20e403203d670df467ea97dde9a4ac40339a8d
diff --git a/examples/proto/BUILD.bazel b/examples/proto/BUILD.bazel
new file mode 100644
index 0000000..9ddf0e3
--- /dev/null
+++ b/examples/proto/BUILD.bazel
@@ -0,0 +1,8 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+
+package(default_visibility = ["//proto:__subpackages__"])
+
+proto_library(
+ name = "common",
+ srcs = ["common.proto"],
+)
diff --git a/examples/proto/basic/BUILD.bazel b/examples/proto/basic/BUILD.bazel
new file mode 100644
index 0000000..9853a2e
--- /dev/null
+++ b/examples/proto/basic/BUILD.bazel
@@ -0,0 +1,24 @@
+load("@rules_rust//proto:proto.bzl", "rust_proto_library")
+load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library")
+
+package(default_visibility = ["//proto:__subpackages__"])
+
+rust_proto_library(
+ name = "common_proto_rust",
+ deps = ["//proto:common"],
+)
+
+rust_library(
+ name = "common_lib",
+ srcs = ["lib.rs"],
+ deps = [":common_proto_rust"],
+)
+
+rust_binary(
+ name = "common_bin",
+ srcs = ["main.rs"],
+ deps = [
+ ":common_lib",
+ ":common_proto_rust",
+ ],
+)
diff --git a/examples/proto/basic/lib.rs b/examples/proto/basic/lib.rs
new file mode 100644
index 0000000..2146b3c
--- /dev/null
+++ b/examples/proto/basic/lib.rs
@@ -0,0 +1,5 @@
+extern crate common_proto_rust;
+
+pub fn do_something(_x: &common_proto_rust::Config) -> bool {
+ true
+}
diff --git a/examples/proto/basic/main.rs b/examples/proto/basic/main.rs
new file mode 100644
index 0000000..12ed82f
--- /dev/null
+++ b/examples/proto/basic/main.rs
@@ -0,0 +1,6 @@
+extern crate common_lib;
+extern crate common_proto_rust;
+
+pub fn main() {
+ common_lib::do_something(&common_proto_rust::Config::new());
+}
diff --git a/examples/proto/common.proto b/examples/proto/common.proto
new file mode 100644
index 0000000..56bac18
--- /dev/null
+++ b/examples/proto/common.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+option java_package = "org.pubref.rules_protobuf.examples";
+option java_outer_classname = "CommonProto";
+
+package common;
+
+// A configuration object. This is used to test the viability of
+// protobuf imports.
+message Config {
+ bool verbose = 1;
+}
+
diff --git a/examples/proto/helloworld/BUILD.bazel b/examples/proto/helloworld/BUILD.bazel
new file mode 100644
index 0000000..db30a9d
--- /dev/null
+++ b/examples/proto/helloworld/BUILD.bazel
@@ -0,0 +1,25 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@rules_rust//proto:proto.bzl", "rust_grpc_library")
+load("@rules_rust//rust:defs.bzl", "rust_test")
+
+proto_library(
+ name = "helloworld",
+ srcs = ["helloworld.proto"],
+ deps = ["//proto:common"],
+)
+
+rust_grpc_library(
+ name = "helloworld_proto",
+ visibility = ["//proto/helloworld:__subpackages__"],
+ deps = [":helloworld"],
+)
+
+rust_test(
+ name = "helloworld_test",
+ srcs = ["helloworld_test.rs"],
+ data = [
+ "//proto/helloworld/greeter_client",
+ "//proto/helloworld/greeter_server",
+ ],
+ deps = ["@rules_rust//tools/runfiles"],
+)
diff --git a/examples/proto/helloworld/greeter_client/BUILD.bazel b/examples/proto/helloworld/greeter_client/BUILD.bazel
new file mode 100644
index 0000000..b35435e
--- /dev/null
+++ b/examples/proto/helloworld/greeter_client/BUILD.bazel
@@ -0,0 +1,11 @@
+load("@rules_rust//proto:toolchain.bzl", "GRPC_COMPILE_DEPS")
+load("@rules_rust//rust:defs.bzl", "rust_binary")
+
+rust_binary(
+ name = "greeter_client",
+ srcs = ["greeter_client.rs"],
+ visibility = ["//proto/helloworld:__subpackages__"],
+ deps = [
+ "//proto/helloworld:helloworld_proto",
+ ] + GRPC_COMPILE_DEPS,
+)
diff --git a/examples/proto/helloworld/greeter_client/greeter_client.rs b/examples/proto/helloworld/greeter_client/greeter_client.rs
new file mode 100644
index 0000000..ade62eb
--- /dev/null
+++ b/examples/proto/helloworld/greeter_client/greeter_client.rs
@@ -0,0 +1,44 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+extern crate grpc;
+extern crate helloworld_proto;
+
+use grpc::ClientStubExt;
+use std::env;
+use std::str::FromStr;
+
+use helloworld_proto::*;
+
+fn parse_args() -> (String, u16) {
+ let mut name = "world".to_owned();
+ let mut port = 50051;
+ for arg in env::args().skip(1) {
+ if let Some(argp) = arg.strip_prefix("-p=") {
+ port = u16::from_str(argp).unwrap()
+ } else {
+ name = arg.to_owned();
+ }
+ }
+ (name, port)
+}
+
+fn main() {
+ let (name, port) = parse_args();
+ let client = GreeterClient::new_plain("::1", port, Default::default()).unwrap();
+ let mut req = HelloRequest::new();
+ req.set_name(name);
+ let resp = client.say_hello(grpc::RequestOptions::new(), req);
+ println!("{:?}", resp.wait());
+}
diff --git a/examples/proto/helloworld/greeter_server/BUILD.bazel b/examples/proto/helloworld/greeter_server/BUILD.bazel
new file mode 100644
index 0000000..616ecb5
--- /dev/null
+++ b/examples/proto/helloworld/greeter_server/BUILD.bazel
@@ -0,0 +1,11 @@
+load("@rules_rust//proto:toolchain.bzl", "GRPC_COMPILE_DEPS")
+load("@rules_rust//rust:defs.bzl", "rust_binary")
+
+rust_binary(
+ name = "greeter_server",
+ srcs = ["greeter_server.rs"],
+ visibility = ["//proto/helloworld:__subpackages__"],
+ deps = [
+ "//proto/helloworld:helloworld_proto",
+ ] + GRPC_COMPILE_DEPS,
+)
diff --git a/examples/proto/helloworld/greeter_server/greeter_server.rs b/examples/proto/helloworld/greeter_server/greeter_server.rs
new file mode 100644
index 0000000..17a09a1
--- /dev/null
+++ b/examples/proto/helloworld/greeter_server/greeter_server.rs
@@ -0,0 +1,58 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+extern crate grpc;
+extern crate helloworld_proto;
+extern crate tls_api_stub;
+
+use std::env;
+use std::str::FromStr;
+use std::thread;
+
+use helloworld_proto::*;
+
+struct GreeterImpl;
+
+impl Greeter for GreeterImpl {
+ fn say_hello(
+ &self,
+ _m: grpc::RequestOptions,
+ req: HelloRequest,
+ ) -> grpc::SingleResponse<HelloReply> {
+ let mut r = HelloReply::new();
+ let name = if req.get_name().is_empty() {
+ "world"
+ } else {
+ req.get_name()
+ };
+ println!("greeting request from {}", name);
+ r.set_message(format!("Hello {}", name));
+ grpc::SingleResponse::completed(r)
+ }
+}
+
+fn main() {
+ let mut server = grpc::ServerBuilder::<tls_api_stub::TlsAcceptor>::new();
+ let port = u16::from_str(&env::args().nth(1).unwrap_or_else(|| "50051".to_owned())).unwrap();
+ server.http.set_port(port);
+ server.add_service(GreeterServer::new_service_def(GreeterImpl));
+ server.http.set_cpu_pool_threads(4);
+ let server = server.build().expect("server");
+ let port = server.local_addr().port().unwrap();
+ println!("greeter server started on port {}", port);
+
+ loop {
+ thread::park();
+ }
+}
diff --git a/examples/proto/helloworld/helloworld.proto b/examples/proto/helloworld/helloworld.proto
new file mode 100644
index 0000000..e0c7598
--- /dev/null
+++ b/examples/proto/helloworld/helloworld.proto
@@ -0,0 +1,23 @@
+
+syntax = "proto3";
+
+import "proto/common.proto";
+
+package helloworld;
+
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+ common.Config config = 2;
+}
+
+// The response message containing the greetings
+message HelloReply {
+ string message = 1;
+}
diff --git a/examples/proto/helloworld/helloworld_test.rs b/examples/proto/helloworld/helloworld_test.rs
new file mode 100644
index 0000000..c82e474
--- /dev/null
+++ b/examples/proto/helloworld/helloworld_test.rs
@@ -0,0 +1,109 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Integration tests for the greeter client/server
+extern crate runfiles;
+
+use std::io::BufRead;
+use std::io::BufReader;
+use std::process::{Child, Command, Stdio};
+use std::str::FromStr;
+
+use runfiles::Runfiles;
+
+struct ServerInfo {
+ process: Child,
+ port: u16,
+}
+
+macro_rules! assert_contains {
+ ($s: expr, $e: expr) => {
+ assert!($s.find($e).is_some());
+ };
+}
+
+impl ServerInfo {
+ fn new() -> ServerInfo {
+ let r = Runfiles::create().unwrap();
+ let mut c =
+ Command::new(r.rlocation("examples/proto/helloworld/greeter_server/greeter_server"))
+ .arg("0")
+ .stdout(Stdio::piped())
+ .spawn()
+ .expect("Unable to start server");
+ let mut port: u16 = 0;
+ {
+ let mut stdout = BufReader::new(c.stdout.as_mut().expect("Failed to open stdout"));
+ let port_prefix = "greeter server started on port ";
+ while port == 0 {
+ let mut line = String::new();
+ stdout
+ .read_line(&mut line)
+ .expect("Waiting for server startup");
+ line = line.trim().to_owned();
+ if let Some(argp) = line.strip_prefix(port_prefix) {
+ port = u16::from_str(argp)
+ .unwrap_or_else(|_| panic!("Invalid port number {}", argp))
+ }
+ }
+ }
+ println!("Started server on port {}", port);
+ ServerInfo { process: c, port }
+ }
+
+ fn run_client_impl(&self, arg: Option<String>) -> String {
+ let r = Runfiles::create().unwrap();
+
+ let mut cmd0 =
+ Command::new(r.rlocation("examples/proto/helloworld/greeter_client/greeter_client"));
+ let cmd = cmd0.arg(format!("-p={}", self.port));
+
+ let output = if let Some(s) = arg { cmd.arg(s) } else { cmd }
+ .output()
+ .expect("Unable to start client");
+ assert!(output.status.success());
+ String::from_utf8(output.stdout).expect("Non UTF-8 output from the client")
+ }
+
+ fn run_client(&self) -> String {
+ self.run_client_impl(None)
+ }
+ fn run_client_with_arg(&self, arg: &str) -> String {
+ self.run_client_impl(Some(arg.to_owned()))
+ }
+
+ fn expect_log(&mut self, log: &str) {
+ let mut reader =
+ BufReader::new(self.process.stdout.as_mut().expect("Failed to open stdout"));
+ let mut line = String::new();
+ reader
+ .read_line(&mut line)
+ .expect("Failed to read line from the server");
+ assert_contains!(line, log);
+ }
+
+ fn destroy(&mut self) {
+ self.process.kill().unwrap();
+ }
+}
+
+#[test]
+fn test_client_server() {
+ let mut s = ServerInfo::new();
+ assert_contains!(s.run_client(), "message: \"Hello world\"");
+ s.expect_log("greeting request from world");
+ assert_contains!(s.run_client_with_arg("thou"), "message: \"Hello thou\"");
+ s.expect_log("greeting request from thou");
+ s.destroy();
+}