├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md ├── proto └── echo.proto ├── Makefile ├── src ├── cmd │ └── main.rs └── rpc │ ├── client.rs │ └── server.rs └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .idea* 2 | target* 3 | nova -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nova" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [[bin]] 9 | name = "rpc-server" 10 | path = "src/rpc/server.rs" 11 | 12 | [[bin]] 13 | name = "rpc-client" 14 | path = "src/rpc/client.rs" 15 | 16 | [[bin]] 17 | name = "cmd" 18 | path = "src/cmd/main.rs" 19 | 20 | 21 | [dependencies] 22 | clap = "3.2.16" 23 | log = "0.4.17" 24 | multi_log = "0.1.2" 25 | simplelog = "0.12.0" 26 | syslog = "6.0.1" 27 | tonic = "0.8" 28 | prost = "0.11" 29 | tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } 30 | futures = "0.3.23" 31 | tokio-stream = "0.1.9" 32 | h2 = "0.3.13" 33 | 34 | [build-dependencies] 35 | tonic-build = "0.8" 36 | 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Kris Nóva 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust template repository. 2 | 3 | An opinionated starting point for rust projects such as 4 | 5 | - systemd services 6 | - command line tools 7 | - client programs 8 | - server programs 9 | - libraries and daemons 10 | 11 | 12 | # Logging 13 | 14 | The program will log in 2 places by default: 15 | 16 | - `stdout` 17 | - `syslog` 18 | 19 | There is a simple `-v` `--verbose` flag that can be toggled on/off to increase and decrease the level of the logs. 20 | 21 | Enabling verbose mode will simply add `Trace` and `Debug` levels to the default configuration. 22 | 23 | | Default Runtime | +Verbose | 24 | |-------------------|----------------| 25 | | Info, Warn, Error | +Trace, +Debug | 26 | 27 | 28 | # Flags 29 | 30 | We prefer flags over environmental variables for runtime configuration. 31 | 32 | Flags can be added to the `main.rs` file following the official [clap examples](https://github.com/clap-rs/clap/tree/v2.33.0/examples) 33 | 34 | 35 | # Clion 36 | 37 | I use [clion](https://www.jetbrains.com/clion/) to develop rust. I use a few features: 38 | 39 | ### Auto Imports 40 | 41 | This will automatically "fix" my `use` statements in the `2021` edition of Rust. 42 | 43 | ``` 44 | Editor > General > Auto Import > Rust 45 | [X] Import out-of-scope items on completion. 46 | ``` 47 | 48 | ### Auto Formatting 49 | 50 | This will automatically `rustfmt` my code when I save. 51 | 52 | ``` 53 | Languages and Frameworks > Rust > Rustfmt 54 | [X] Run rustfmt on save 55 | ``` 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /proto/echo.proto: -------------------------------------------------------------------------------- 1 | /*===========================================================================*\ 2 | * MIT License Copyright (c) 2022 Kris Nóva * 3 | * * 4 | * ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ * 5 | * ┃ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ ┃ * 6 | * ┃ ████╗ ██║██╔═████╗██║ ██║██╔══██╗ ┃ * 7 | * ┃ ██╔██╗ ██║██║██╔██║██║ ██║███████║ ┃ * 8 | * ┃ ██║╚██╗██║████╔╝██║╚██╗ ██╔╝██╔══██║ ┃ * 9 | * ┃ ██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║ ┃ * 10 | * ┃ ╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝ ┃ * 11 | * ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ * 12 | * * 13 | * This machine kills fascists. * 14 | * * 15 | \*===========================================================================*/ 16 | 17 | syntax = "proto3"; 18 | 19 | package proto.echo; // This is arbitrary, set it to your directory structure 20 | 21 | // EchoRequest is the request for echo. 22 | message EchoRequest { 23 | string message = 1; 24 | } 25 | 26 | // EchoResponse is the response for echo. 27 | message EchoResponse { 28 | string message = 1; 29 | } 30 | 31 | // Echo is the echo service. 32 | service Echo { 33 | // UnaryEcho is unary echo. 34 | rpc UnaryEcho(EchoRequest) returns (EchoResponse) {} 35 | // ServerStreamingEcho is server side streaming. 36 | rpc ServerStreamingEcho(EchoRequest) returns (stream EchoResponse) {} 37 | // ClientStreamingEcho is client side streaming. 38 | rpc ClientStreamingEcho(stream EchoRequest) returns (EchoResponse) {} 39 | // BidirectionalStreamingEcho is bidi streaming. 40 | rpc BidirectionalStreamingEcho(stream EchoRequest) returns (stream EchoResponse) {} 41 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # =========================================================================== # 2 | # MIT License Copyright (c) 2022 Kris Nóva # 3 | # # 4 | # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ # 5 | # ┃ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ ┃ # 6 | # ┃ ████╗ ██║██╔═████╗██║ ██║██╔══██╗ ┃ # 7 | # ┃ ██╔██╗ ██║██║██╔██║██║ ██║███████║ ┃ # 8 | # ┃ ██║╚██╗██║████╔╝██║╚██╗ ██╔╝██╔══██║ ┃ # 9 | # ┃ ██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║ ┃ # 10 | # ┃ ╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝ ┃ # 11 | # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ # 12 | # # 13 | # This machine kills fascists. # 14 | # # 15 | # =========================================================================== # 16 | 17 | all: compile 18 | 19 | #version ?= 0.0.1 20 | executable ?= nova 21 | #org ?= kris-nova 22 | #authorname ?= Kris Nóva 23 | #authoremail ?= kris@nivenly.com 24 | #license ?= MIT 25 | #year ?= 2022 26 | #copyright ?= Copyright (c) $(year) 27 | 28 | compile: ## Compile for the local architecture ⚙ 29 | @cargo build --release 30 | 31 | install: ## Install the program to /usr/bin 🎉 32 | @echo "Installing..." 33 | @cargo install --path . 34 | cp -v ./target/release/$(executable) /usr/bin/$(executable) 35 | 36 | #test: clean compile install ## 🤓 Run go tests 37 | # @echo "Testing..." 38 | # go test -v ./... 39 | 40 | clean: ## Clean your artifacts 🧼 41 | @echo "Cleaning..." 42 | @cargo clean 43 | @rm -rvf target/* 44 | @rm -rvf $(executable) 45 | 46 | #.PHONY: release 47 | #release: ## Make the binaries for a GitHub release 📦 48 | # mkdir -p release 49 | # GOOS="linux" GOARCH="amd64" go build -ldflags "-X 'github.com/$(org)/$(target).Version=$(version)'" -o release/$(target)-linux-amd64 cmd/*.go 50 | # GOOS="linux" GOARCH="arm" go build -ldflags "-X 'github.com/$(org)/$(target).Version=$(version)'" -o release/$(target)-linux-arm cmd/*.go 51 | # GOOS="linux" GOARCH="arm64" go build -ldflags "-X 'github.com/$(org)/$(target).Version=$(version)'" -o release/$(target)-linux-arm64 cmd/*.go 52 | # GOOS="linux" GOARCH="386" go build -ldflags "-X 'github.com/$(org)/$(target).Version=$(version)'" -o release/$(target)-linux-386 cmd/*.go 53 | # GOOS="darwin" GOARCH="amd64" go build -ldflags "-X 'github.com/$(org)/$(target).Version=$(version)'" -o release/$(target)-darwin-amd64 cmd/*.go 54 | 55 | .PHONY: help 56 | help: ## 🤔 Show help messages for make targets 57 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' 58 | -------------------------------------------------------------------------------- /src/cmd/main.rs: -------------------------------------------------------------------------------- 1 | /*===========================================================================*\ 2 | * MIT License Copyright (c) 2022 Kris Nóva * 3 | * * 4 | * ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ * 5 | * ┃ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ ┃ * 6 | * ┃ ████╗ ██║██╔═████╗██║ ██║██╔══██╗ ┃ * 7 | * ┃ ██╔██╗ ██║██║██╔██║██║ ██║███████║ ┃ * 8 | * ┃ ██║╚██╗██║████╔╝██║╚██╗ ██╔╝██╔══██║ ┃ * 9 | * ┃ ██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║ ┃ * 10 | * ┃ ╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝ ┃ * 11 | * ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ * 12 | * * 13 | * This machine kills fascists. * 14 | * * 15 | \*===========================================================================*/ 16 | 17 | extern crate core; 18 | 19 | use clap::*; 20 | use log::*; 21 | use syslog::*; 22 | 23 | const EXIT_OKAY: i32 = 0; 24 | //const EXIT_ERROR: i32 = 1; 25 | 26 | fn runtime() -> i32 { 27 | return EXIT_OKAY; 28 | } 29 | 30 | fn runtime_environment() { 31 | let name = "nova"; 32 | 33 | // Initialize the program 34 | let matches = App::new("Nova") 35 | .version("1.0") 36 | .author("Kris Nóva ") 37 | .about(name) 38 | .arg( 39 | Arg::with_name("verbose") 40 | .short('v') 41 | .long("verbose") 42 | .help("Toggle the verbosity bit.") // With <3 from @togglebit 43 | .takes_value(false), 44 | ) 45 | .get_matches(); 46 | 47 | // The logger will log to stdout and the syslog by default. 48 | // We hold the opinion that the program is either "verbose" 49 | // or it's not. 50 | // 51 | // Normal mode: Info, Warn, Error 52 | // Verbose mode: Debug, Trace, Info, Warn, Error 53 | let logger_level = if matches.is_present("verbose") { 54 | log::Level::Trace 55 | } else { 56 | log::Level::Info 57 | }; 58 | 59 | // Syslog formatter 60 | let formatter = Formatter3164 { 61 | facility: Facility::LOG_USER, 62 | hostname: None, 63 | process: name.into(), 64 | pid: 0, 65 | }; 66 | 67 | // Initialize the logger 68 | let logger_simple = 69 | simplelog::SimpleLogger::new(logger_level.to_level_filter(), simplelog::Config::default()); 70 | let logger_syslog = syslog::unix(formatter).unwrap(); 71 | let _ = match multi_log::MultiLogger::init( 72 | vec![logger_simple, Box::new(BasicLogger::new(logger_syslog))], 73 | logger_level, 74 | ) { 75 | Ok(_) => {} 76 | Err(e) => panic!("unable to connect to syslog: {:?}", e), 77 | }; 78 | 79 | // Initialize the program 80 | info!("*"); 81 | info!("*"); 82 | info!("* Runtime environment initialized: {}", name); 83 | info!("* -> Syslog process name: {}", name); 84 | debug!("* Runtime **debugging** enabled: {}", name); 85 | info!("*"); 86 | info!("*"); 87 | } 88 | 89 | fn main() { 90 | runtime_environment(); 91 | let exit_code = runtime(); 92 | std::process::exit(exit_code); 93 | } 94 | -------------------------------------------------------------------------------- /src/rpc/client.rs: -------------------------------------------------------------------------------- 1 | /*===========================================================================*\ 2 | * MIT License Copyright (c) 2022 Kris Nóva * 3 | * * 4 | * ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ * 5 | * ┃ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ ┃ * 6 | * ┃ ████╗ ██║██╔═████╗██║ ██║██╔══██╗ ┃ * 7 | * ┃ ██╔██╗ ██║██║██╔██║██║ ██║███████║ ┃ * 8 | * ┃ ██║╚██╗██║████╔╝██║╚██╗ ██╔╝██╔══██║ ┃ * 9 | * ┃ ██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║ ┃ * 10 | * ┃ ╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝ ┃ * 11 | * ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ * 12 | * * 13 | * This machine kills fascists. * 14 | * * 15 | \*===========================================================================*/ 16 | 17 | pub mod pb { 18 | tonic::include_proto!("proto.echo"); 19 | } 20 | 21 | use futures::stream::Stream; 22 | use std::time::Duration; 23 | use tokio_stream::StreamExt; 24 | use tonic::transport::Channel; 25 | 26 | use pb::{echo_client::EchoClient, EchoRequest}; 27 | 28 | fn echo_requests_iter() -> impl Stream { 29 | tokio_stream::iter(1..usize::MAX).map(|i| EchoRequest { 30 | message: format!("msg {:02}", i), 31 | }) 32 | } 33 | 34 | async fn streaming_echo(client: &mut EchoClient, num: usize) { 35 | let stream = client 36 | .server_streaming_echo(EchoRequest { 37 | message: "foo".into(), 38 | }) 39 | .await 40 | .unwrap() 41 | .into_inner(); 42 | 43 | // stream is infinite - take just 5 elements and then disconnect 44 | let mut stream = stream.take(num); 45 | while let Some(item) = stream.next().await { 46 | println!("\treceived: {}", item.unwrap().message); 47 | } 48 | // stream is droped here and the disconnect info is send to server 49 | } 50 | 51 | async fn bidirectional_streaming_echo(client: &mut EchoClient, num: usize) { 52 | let in_stream = echo_requests_iter().take(num); 53 | 54 | let response = client 55 | .bidirectional_streaming_echo(in_stream) 56 | .await 57 | .unwrap(); 58 | 59 | let mut resp_stream = response.into_inner(); 60 | 61 | while let Some(received) = resp_stream.next().await { 62 | let received = received.unwrap(); 63 | println!("\treceived message: `{}`", received.message); 64 | } 65 | } 66 | 67 | async fn bidirectional_streaming_echo_throttle(client: &mut EchoClient, dur: Duration) { 68 | let in_stream = echo_requests_iter().throttle(dur); 69 | 70 | let response = client 71 | .bidirectional_streaming_echo(in_stream) 72 | .await 73 | .unwrap(); 74 | 75 | let mut resp_stream = response.into_inner(); 76 | 77 | while let Some(received) = resp_stream.next().await { 78 | let received = received.unwrap(); 79 | println!("\treceived message: `{}`", received.message); 80 | } 81 | } 82 | 83 | #[tokio::main] 84 | async fn main() -> Result<(), Box> { 85 | let mut client = EchoClient::connect("http://[::1]:50051").await.unwrap(); 86 | 87 | println!("Streaming echo:"); 88 | streaming_echo(&mut client, 5).await; 89 | tokio::time::sleep(Duration::from_secs(1)).await; //do not mess server println functions 90 | 91 | // Echo stream that sends 17 requests then graceful end that connection 92 | println!("\r\nBidirectional stream echo:"); 93 | bidirectional_streaming_echo(&mut client, 17).await; 94 | 95 | // Echo stream that sends up to `usize::MAX` requets. One request each 2s. 96 | // Exiting client with CTRL+C demonstrate how to distinguish broken pipe from 97 | //graceful client disconnection (above example) on the server side. 98 | println!("\r\nBidirectional stream echo (kill client with CTLR+C):"); 99 | bidirectional_streaming_echo_throttle(&mut client, Duration::from_secs(2)).await; 100 | 101 | Ok(()) 102 | } -------------------------------------------------------------------------------- /src/rpc/server.rs: -------------------------------------------------------------------------------- 1 | /*===========================================================================*\ 2 | * MIT License Copyright (c) 2022 Kris Nóva * 3 | * * 4 | * ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ * 5 | * ┃ ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗ ┃ * 6 | * ┃ ████╗ ██║██╔═████╗██║ ██║██╔══██╗ ┃ * 7 | * ┃ ██╔██╗ ██║██║██╔██║██║ ██║███████║ ┃ * 8 | * ┃ ██║╚██╗██║████╔╝██║╚██╗ ██╔╝██╔══██║ ┃ * 9 | * ┃ ██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║ ┃ * 10 | * ┃ ╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝ ┃ * 11 | * ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ * 12 | * * 13 | * This machine kills fascists. * 14 | * * 15 | \*===========================================================================*/ 16 | 17 | pub mod pb { 18 | tonic::include_proto!("proto.echo"); 19 | } 20 | 21 | use futures::Stream; 22 | use std::{error::Error, io::ErrorKind, net::ToSocketAddrs, pin::Pin, time::Duration}; 23 | use tokio::sync::mpsc; 24 | use tokio_stream::{wrappers::ReceiverStream, StreamExt}; 25 | use tonic::{transport::Server, Request, Response, Status, Streaming}; 26 | 27 | use pb::{EchoRequest, EchoResponse}; 28 | 29 | type EchoResult = Result, Status>; 30 | type ResponseStream = Pin> + Send>>; 31 | 32 | fn match_for_io_error(err_status: &Status) -> Option<&std::io::Error> { 33 | let mut err: &(dyn Error + 'static) = err_status; 34 | 35 | loop { 36 | if let Some(io_err) = err.downcast_ref::() { 37 | return Some(io_err); 38 | } 39 | 40 | // h2::Error do not expose std::io::Error with `source()` 41 | // https://github.com/hyperium/h2/pull/462 42 | if let Some(h2_err) = err.downcast_ref::() { 43 | if let Some(io_err) = h2_err.get_io() { 44 | return Some(io_err); 45 | } 46 | } 47 | 48 | err = match err.source() { 49 | Some(err) => err, 50 | None => return None, 51 | }; 52 | } 53 | } 54 | 55 | #[derive(Debug)] 56 | pub struct EchoServer {} 57 | 58 | #[tonic::async_trait] 59 | impl pb::echo_server::Echo for EchoServer { 60 | async fn unary_echo(&self, _: Request) -> EchoResult { 61 | Err(Status::unimplemented("not implemented")) 62 | } 63 | 64 | type ServerStreamingEchoStream = ResponseStream; 65 | 66 | async fn server_streaming_echo( 67 | &self, 68 | req: Request, 69 | ) -> EchoResult { 70 | println!("EchoServer::server_streaming_echo"); 71 | println!("\tclient connected from: {:?}", req.remote_addr()); 72 | 73 | // creating infinite stream with requested message 74 | let repeat = std::iter::repeat(EchoResponse { 75 | message: req.into_inner().message, 76 | }); 77 | let mut stream = Box::pin(tokio_stream::iter(repeat).throttle(Duration::from_millis(200))); 78 | 79 | // spawn and channel are required if you want handle "disconnect" functionality 80 | // the `out_stream` will not be polled after client disconnect 81 | let (tx, rx) = mpsc::channel(128); 82 | tokio::spawn(async move { 83 | while let Some(item) = stream.next().await { 84 | match tx.send(Result::<_, Status>::Ok(item)).await { 85 | Ok(_) => { 86 | // item (server response) was queued to be send to client 87 | } 88 | Err(_item) => { 89 | // output_stream was build from rx and both are dropped 90 | break; 91 | } 92 | } 93 | } 94 | println!("\tclient disconnected"); 95 | }); 96 | 97 | let output_stream = ReceiverStream::new(rx); 98 | Ok(Response::new( 99 | Box::pin(output_stream) as Self::ServerStreamingEchoStream 100 | )) 101 | } 102 | 103 | async fn client_streaming_echo( 104 | &self, 105 | _: Request>, 106 | ) -> EchoResult { 107 | Err(Status::unimplemented("not implemented")) 108 | } 109 | 110 | type BidirectionalStreamingEchoStream = ResponseStream; 111 | 112 | async fn bidirectional_streaming_echo( 113 | &self, 114 | req: Request>, 115 | ) -> EchoResult { 116 | println!("EchoServer::bidirectional_streaming_echo"); 117 | 118 | let mut in_stream = req.into_inner(); 119 | let (tx, rx) = mpsc::channel(128); 120 | 121 | // this spawn here is required if you want to handle connection error. 122 | // If we just map `in_stream` and write it back as `out_stream` the `out_stream` 123 | // will be drooped when connection error occurs and error will never be propagated 124 | // to mapped version of `in_stream`. 125 | tokio::spawn(async move { 126 | while let Some(result) = in_stream.next().await { 127 | match result { 128 | Ok(v) => tx 129 | .send(Ok(EchoResponse { message: v.message })) 130 | .await 131 | .expect("working rx"), 132 | Err(err) => { 133 | if let Some(io_err) = match_for_io_error(&err) { 134 | if io_err.kind() == ErrorKind::BrokenPipe { 135 | // here you can handle special case when client 136 | // disconnected in unexpected way 137 | eprintln!("\tclient disconnected: broken pipe"); 138 | break; 139 | } 140 | } 141 | 142 | match tx.send(Err(err)).await { 143 | Ok(_) => (), 144 | Err(_err) => break, // response was droped 145 | } 146 | } 147 | } 148 | } 149 | println!("\tstream ended"); 150 | }); 151 | 152 | // echo just write the same data that was received 153 | let out_stream = ReceiverStream::new(rx); 154 | 155 | Ok(Response::new( 156 | Box::pin(out_stream) as Self::BidirectionalStreamingEchoStream 157 | )) 158 | } 159 | } 160 | 161 | #[tokio::main] 162 | async fn main() -> Result<(), Box> { 163 | let server = EchoServer {}; 164 | Server::builder() 165 | .add_service(pb::echo_server::EchoServer::new(server)) 166 | .serve("[::1]:50051".to_socket_addrs().unwrap().next().unwrap()) 167 | .await 168 | .unwrap(); 169 | 170 | Ok(()) 171 | } 172 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anyhow" 7 | version = "1.0.61" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8" 10 | 11 | [[package]] 12 | name = "async-stream" 13 | version = "0.3.3" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" 16 | dependencies = [ 17 | "async-stream-impl", 18 | "futures-core", 19 | ] 20 | 21 | [[package]] 22 | name = "async-stream-impl" 23 | version = "0.3.3" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" 26 | dependencies = [ 27 | "proc-macro2", 28 | "quote", 29 | "syn", 30 | ] 31 | 32 | [[package]] 33 | name = "async-trait" 34 | version = "0.1.57" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" 37 | dependencies = [ 38 | "proc-macro2", 39 | "quote", 40 | "syn", 41 | ] 42 | 43 | [[package]] 44 | name = "atty" 45 | version = "0.2.14" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 48 | dependencies = [ 49 | "hermit-abi", 50 | "libc", 51 | "winapi", 52 | ] 53 | 54 | [[package]] 55 | name = "autocfg" 56 | version = "1.1.0" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 59 | 60 | [[package]] 61 | name = "axum" 62 | version = "0.5.15" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "9de18bc5f2e9df8f52da03856bf40e29b747de5a84e43aefff90e3dc4a21529b" 65 | dependencies = [ 66 | "async-trait", 67 | "axum-core", 68 | "bitflags", 69 | "bytes", 70 | "futures-util", 71 | "http", 72 | "http-body", 73 | "hyper", 74 | "itoa", 75 | "matchit", 76 | "memchr", 77 | "mime", 78 | "percent-encoding", 79 | "pin-project-lite", 80 | "serde", 81 | "sync_wrapper", 82 | "tokio", 83 | "tower", 84 | "tower-http", 85 | "tower-layer", 86 | "tower-service", 87 | ] 88 | 89 | [[package]] 90 | name = "axum-core" 91 | version = "0.2.7" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "e4f44a0e6200e9d11a1cdc989e4b358f6e3d354fbf48478f345a17f4e43f8635" 94 | dependencies = [ 95 | "async-trait", 96 | "bytes", 97 | "futures-util", 98 | "http", 99 | "http-body", 100 | "mime", 101 | ] 102 | 103 | [[package]] 104 | name = "base64" 105 | version = "0.13.0" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 108 | 109 | [[package]] 110 | name = "bitflags" 111 | version = "1.3.2" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 114 | 115 | [[package]] 116 | name = "bytes" 117 | version = "1.2.1" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" 120 | 121 | [[package]] 122 | name = "cfg-if" 123 | version = "1.0.0" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 126 | 127 | [[package]] 128 | name = "clap" 129 | version = "3.2.17" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b" 132 | dependencies = [ 133 | "atty", 134 | "bitflags", 135 | "clap_lex", 136 | "indexmap", 137 | "strsim", 138 | "termcolor", 139 | "textwrap", 140 | ] 141 | 142 | [[package]] 143 | name = "clap_lex" 144 | version = "0.2.4" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" 147 | dependencies = [ 148 | "os_str_bytes", 149 | ] 150 | 151 | [[package]] 152 | name = "either" 153 | version = "1.7.0" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" 156 | 157 | [[package]] 158 | name = "error-chain" 159 | version = "0.12.4" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" 162 | dependencies = [ 163 | "version_check", 164 | ] 165 | 166 | [[package]] 167 | name = "fastrand" 168 | version = "1.8.0" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" 171 | dependencies = [ 172 | "instant", 173 | ] 174 | 175 | [[package]] 176 | name = "fixedbitset" 177 | version = "0.4.2" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 180 | 181 | [[package]] 182 | name = "fnv" 183 | version = "1.0.7" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 186 | 187 | [[package]] 188 | name = "futures" 189 | version = "0.3.23" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" 192 | dependencies = [ 193 | "futures-channel", 194 | "futures-core", 195 | "futures-executor", 196 | "futures-io", 197 | "futures-sink", 198 | "futures-task", 199 | "futures-util", 200 | ] 201 | 202 | [[package]] 203 | name = "futures-channel" 204 | version = "0.3.23" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" 207 | dependencies = [ 208 | "futures-core", 209 | "futures-sink", 210 | ] 211 | 212 | [[package]] 213 | name = "futures-core" 214 | version = "0.3.23" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" 217 | 218 | [[package]] 219 | name = "futures-executor" 220 | version = "0.3.23" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" 223 | dependencies = [ 224 | "futures-core", 225 | "futures-task", 226 | "futures-util", 227 | ] 228 | 229 | [[package]] 230 | name = "futures-io" 231 | version = "0.3.23" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" 234 | 235 | [[package]] 236 | name = "futures-macro" 237 | version = "0.3.23" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" 240 | dependencies = [ 241 | "proc-macro2", 242 | "quote", 243 | "syn", 244 | ] 245 | 246 | [[package]] 247 | name = "futures-sink" 248 | version = "0.3.23" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" 251 | 252 | [[package]] 253 | name = "futures-task" 254 | version = "0.3.23" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" 257 | 258 | [[package]] 259 | name = "futures-util" 260 | version = "0.3.23" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" 263 | dependencies = [ 264 | "futures-channel", 265 | "futures-core", 266 | "futures-io", 267 | "futures-macro", 268 | "futures-sink", 269 | "futures-task", 270 | "memchr", 271 | "pin-project-lite", 272 | "pin-utils", 273 | "slab", 274 | ] 275 | 276 | [[package]] 277 | name = "getrandom" 278 | version = "0.2.7" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" 281 | dependencies = [ 282 | "cfg-if", 283 | "libc", 284 | "wasi", 285 | ] 286 | 287 | [[package]] 288 | name = "h2" 289 | version = "0.3.13" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" 292 | dependencies = [ 293 | "bytes", 294 | "fnv", 295 | "futures-core", 296 | "futures-sink", 297 | "futures-util", 298 | "http", 299 | "indexmap", 300 | "slab", 301 | "tokio", 302 | "tokio-util", 303 | "tracing", 304 | ] 305 | 306 | [[package]] 307 | name = "hashbrown" 308 | version = "0.12.3" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 311 | 312 | [[package]] 313 | name = "heck" 314 | version = "0.4.0" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 317 | 318 | [[package]] 319 | name = "hermit-abi" 320 | version = "0.1.19" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 323 | dependencies = [ 324 | "libc", 325 | ] 326 | 327 | [[package]] 328 | name = "hostname" 329 | version = "0.3.1" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" 332 | dependencies = [ 333 | "libc", 334 | "match_cfg", 335 | "winapi", 336 | ] 337 | 338 | [[package]] 339 | name = "http" 340 | version = "0.2.8" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" 343 | dependencies = [ 344 | "bytes", 345 | "fnv", 346 | "itoa", 347 | ] 348 | 349 | [[package]] 350 | name = "http-body" 351 | version = "0.4.5" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 354 | dependencies = [ 355 | "bytes", 356 | "http", 357 | "pin-project-lite", 358 | ] 359 | 360 | [[package]] 361 | name = "http-range-header" 362 | version = "0.3.0" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" 365 | 366 | [[package]] 367 | name = "httparse" 368 | version = "1.7.1" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" 371 | 372 | [[package]] 373 | name = "httpdate" 374 | version = "1.0.2" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 377 | 378 | [[package]] 379 | name = "hyper" 380 | version = "0.14.20" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" 383 | dependencies = [ 384 | "bytes", 385 | "futures-channel", 386 | "futures-core", 387 | "futures-util", 388 | "h2", 389 | "http", 390 | "http-body", 391 | "httparse", 392 | "httpdate", 393 | "itoa", 394 | "pin-project-lite", 395 | "socket2", 396 | "tokio", 397 | "tower-service", 398 | "tracing", 399 | "want", 400 | ] 401 | 402 | [[package]] 403 | name = "hyper-timeout" 404 | version = "0.4.1" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" 407 | dependencies = [ 408 | "hyper", 409 | "pin-project-lite", 410 | "tokio", 411 | "tokio-io-timeout", 412 | ] 413 | 414 | [[package]] 415 | name = "indexmap" 416 | version = "1.9.1" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" 419 | dependencies = [ 420 | "autocfg", 421 | "hashbrown", 422 | ] 423 | 424 | [[package]] 425 | name = "instant" 426 | version = "0.1.12" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 429 | dependencies = [ 430 | "cfg-if", 431 | ] 432 | 433 | [[package]] 434 | name = "itertools" 435 | version = "0.10.3" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" 438 | dependencies = [ 439 | "either", 440 | ] 441 | 442 | [[package]] 443 | name = "itoa" 444 | version = "1.0.3" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" 447 | 448 | [[package]] 449 | name = "lazy_static" 450 | version = "1.4.0" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 453 | 454 | [[package]] 455 | name = "libc" 456 | version = "0.2.131" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" 459 | 460 | [[package]] 461 | name = "log" 462 | version = "0.4.17" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 465 | dependencies = [ 466 | "cfg-if", 467 | ] 468 | 469 | [[package]] 470 | name = "match_cfg" 471 | version = "0.1.0" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" 474 | 475 | [[package]] 476 | name = "matchit" 477 | version = "0.5.0" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" 480 | 481 | [[package]] 482 | name = "memchr" 483 | version = "2.5.0" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 486 | 487 | [[package]] 488 | name = "mime" 489 | version = "0.3.16" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 492 | 493 | [[package]] 494 | name = "mio" 495 | version = "0.8.4" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" 498 | dependencies = [ 499 | "libc", 500 | "log", 501 | "wasi", 502 | "windows-sys", 503 | ] 504 | 505 | [[package]] 506 | name = "multi_log" 507 | version = "0.1.2" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "ad56bb3c7c7c15b4e25de86c9123e886e5f80a0c03ace219b453b081c2bf20d7" 510 | dependencies = [ 511 | "log", 512 | ] 513 | 514 | [[package]] 515 | name = "multimap" 516 | version = "0.8.3" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" 519 | 520 | [[package]] 521 | name = "nova" 522 | version = "0.1.0" 523 | dependencies = [ 524 | "clap", 525 | "futures", 526 | "h2", 527 | "log", 528 | "multi_log", 529 | "prost", 530 | "simplelog", 531 | "syslog", 532 | "tokio", 533 | "tokio-stream", 534 | "tonic", 535 | "tonic-build", 536 | ] 537 | 538 | [[package]] 539 | name = "num_cpus" 540 | version = "1.13.1" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 543 | dependencies = [ 544 | "hermit-abi", 545 | "libc", 546 | ] 547 | 548 | [[package]] 549 | name = "num_threads" 550 | version = "0.1.6" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" 553 | dependencies = [ 554 | "libc", 555 | ] 556 | 557 | [[package]] 558 | name = "once_cell" 559 | version = "1.13.0" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" 562 | 563 | [[package]] 564 | name = "os_str_bytes" 565 | version = "6.2.0" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" 568 | 569 | [[package]] 570 | name = "percent-encoding" 571 | version = "2.1.0" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 574 | 575 | [[package]] 576 | name = "petgraph" 577 | version = "0.6.2" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" 580 | dependencies = [ 581 | "fixedbitset", 582 | "indexmap", 583 | ] 584 | 585 | [[package]] 586 | name = "pin-project" 587 | version = "1.0.11" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260" 590 | dependencies = [ 591 | "pin-project-internal", 592 | ] 593 | 594 | [[package]] 595 | name = "pin-project-internal" 596 | version = "1.0.11" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" 599 | dependencies = [ 600 | "proc-macro2", 601 | "quote", 602 | "syn", 603 | ] 604 | 605 | [[package]] 606 | name = "pin-project-lite" 607 | version = "0.2.9" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 610 | 611 | [[package]] 612 | name = "pin-utils" 613 | version = "0.1.0" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 616 | 617 | [[package]] 618 | name = "ppv-lite86" 619 | version = "0.2.16" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 622 | 623 | [[package]] 624 | name = "prettyplease" 625 | version = "0.1.18" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "697ae720ee02011f439e0701db107ffe2916d83f718342d65d7f8bf7b8a5fee9" 628 | dependencies = [ 629 | "proc-macro2", 630 | "syn", 631 | ] 632 | 633 | [[package]] 634 | name = "proc-macro2" 635 | version = "1.0.43" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" 638 | dependencies = [ 639 | "unicode-ident", 640 | ] 641 | 642 | [[package]] 643 | name = "prost" 644 | version = "0.11.0" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "399c3c31cdec40583bb68f0b18403400d01ec4289c383aa047560439952c4dd7" 647 | dependencies = [ 648 | "bytes", 649 | "prost-derive", 650 | ] 651 | 652 | [[package]] 653 | name = "prost-build" 654 | version = "0.11.1" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "7f835c582e6bd972ba8347313300219fed5bfa52caf175298d860b61ff6069bb" 657 | dependencies = [ 658 | "bytes", 659 | "heck", 660 | "itertools", 661 | "lazy_static", 662 | "log", 663 | "multimap", 664 | "petgraph", 665 | "prost", 666 | "prost-types", 667 | "regex", 668 | "tempfile", 669 | "which", 670 | ] 671 | 672 | [[package]] 673 | name = "prost-derive" 674 | version = "0.11.0" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "7345d5f0e08c0536d7ac7229952590239e77abf0a0100a1b1d890add6ea96364" 677 | dependencies = [ 678 | "anyhow", 679 | "itertools", 680 | "proc-macro2", 681 | "quote", 682 | "syn", 683 | ] 684 | 685 | [[package]] 686 | name = "prost-types" 687 | version = "0.11.1" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "4dfaa718ad76a44b3415e6c4d53b17c8f99160dcb3a99b10470fce8ad43f6e3e" 690 | dependencies = [ 691 | "bytes", 692 | "prost", 693 | ] 694 | 695 | [[package]] 696 | name = "quote" 697 | version = "1.0.21" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 700 | dependencies = [ 701 | "proc-macro2", 702 | ] 703 | 704 | [[package]] 705 | name = "rand" 706 | version = "0.8.5" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 709 | dependencies = [ 710 | "libc", 711 | "rand_chacha", 712 | "rand_core", 713 | ] 714 | 715 | [[package]] 716 | name = "rand_chacha" 717 | version = "0.3.1" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 720 | dependencies = [ 721 | "ppv-lite86", 722 | "rand_core", 723 | ] 724 | 725 | [[package]] 726 | name = "rand_core" 727 | version = "0.6.3" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" 730 | dependencies = [ 731 | "getrandom", 732 | ] 733 | 734 | [[package]] 735 | name = "redox_syscall" 736 | version = "0.2.16" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 739 | dependencies = [ 740 | "bitflags", 741 | ] 742 | 743 | [[package]] 744 | name = "regex" 745 | version = "1.6.0" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" 748 | dependencies = [ 749 | "regex-syntax", 750 | ] 751 | 752 | [[package]] 753 | name = "regex-syntax" 754 | version = "0.6.27" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" 757 | 758 | [[package]] 759 | name = "remove_dir_all" 760 | version = "0.5.3" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 763 | dependencies = [ 764 | "winapi", 765 | ] 766 | 767 | [[package]] 768 | name = "serde" 769 | version = "1.0.143" 770 | source = "registry+https://github.com/rust-lang/crates.io-index" 771 | checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" 772 | 773 | [[package]] 774 | name = "simplelog" 775 | version = "0.12.0" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "48dfff04aade74dd495b007c831cd6f4e0cee19c344dd9dc0884c0289b70a786" 778 | dependencies = [ 779 | "log", 780 | "termcolor", 781 | "time", 782 | ] 783 | 784 | [[package]] 785 | name = "slab" 786 | version = "0.4.7" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 789 | dependencies = [ 790 | "autocfg", 791 | ] 792 | 793 | [[package]] 794 | name = "socket2" 795 | version = "0.4.4" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" 798 | dependencies = [ 799 | "libc", 800 | "winapi", 801 | ] 802 | 803 | [[package]] 804 | name = "strsim" 805 | version = "0.10.0" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 808 | 809 | [[package]] 810 | name = "syn" 811 | version = "1.0.99" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" 814 | dependencies = [ 815 | "proc-macro2", 816 | "quote", 817 | "unicode-ident", 818 | ] 819 | 820 | [[package]] 821 | name = "sync_wrapper" 822 | version = "0.1.1" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" 825 | 826 | [[package]] 827 | name = "syslog" 828 | version = "6.0.1" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "978044cc68150ad5e40083c9f6a725e6fd02d7ba1bcf691ec2ff0d66c0b41acc" 831 | dependencies = [ 832 | "error-chain", 833 | "hostname", 834 | "libc", 835 | "log", 836 | "time", 837 | ] 838 | 839 | [[package]] 840 | name = "tempfile" 841 | version = "3.3.0" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 844 | dependencies = [ 845 | "cfg-if", 846 | "fastrand", 847 | "libc", 848 | "redox_syscall", 849 | "remove_dir_all", 850 | "winapi", 851 | ] 852 | 853 | [[package]] 854 | name = "termcolor" 855 | version = "1.1.3" 856 | source = "registry+https://github.com/rust-lang/crates.io-index" 857 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 858 | dependencies = [ 859 | "winapi-util", 860 | ] 861 | 862 | [[package]] 863 | name = "textwrap" 864 | version = "0.15.0" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" 867 | 868 | [[package]] 869 | name = "time" 870 | version = "0.3.13" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" 873 | dependencies = [ 874 | "itoa", 875 | "libc", 876 | "num_threads", 877 | "time-macros", 878 | ] 879 | 880 | [[package]] 881 | name = "time-macros" 882 | version = "0.2.4" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" 885 | 886 | [[package]] 887 | name = "tokio" 888 | version = "1.20.1" 889 | source = "registry+https://github.com/rust-lang/crates.io-index" 890 | checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" 891 | dependencies = [ 892 | "autocfg", 893 | "bytes", 894 | "libc", 895 | "memchr", 896 | "mio", 897 | "num_cpus", 898 | "once_cell", 899 | "pin-project-lite", 900 | "socket2", 901 | "tokio-macros", 902 | "winapi", 903 | ] 904 | 905 | [[package]] 906 | name = "tokio-io-timeout" 907 | version = "1.2.0" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" 910 | dependencies = [ 911 | "pin-project-lite", 912 | "tokio", 913 | ] 914 | 915 | [[package]] 916 | name = "tokio-macros" 917 | version = "1.8.0" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" 920 | dependencies = [ 921 | "proc-macro2", 922 | "quote", 923 | "syn", 924 | ] 925 | 926 | [[package]] 927 | name = "tokio-stream" 928 | version = "0.1.9" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" 931 | dependencies = [ 932 | "futures-core", 933 | "pin-project-lite", 934 | "tokio", 935 | ] 936 | 937 | [[package]] 938 | name = "tokio-util" 939 | version = "0.7.3" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" 942 | dependencies = [ 943 | "bytes", 944 | "futures-core", 945 | "futures-sink", 946 | "pin-project-lite", 947 | "tokio", 948 | "tracing", 949 | ] 950 | 951 | [[package]] 952 | name = "tonic" 953 | version = "0.8.0" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | checksum = "498f271adc46acce75d66f639e4d35b31b2394c295c82496727dafa16d465dd2" 956 | dependencies = [ 957 | "async-stream", 958 | "async-trait", 959 | "axum", 960 | "base64", 961 | "bytes", 962 | "futures-core", 963 | "futures-util", 964 | "h2", 965 | "http", 966 | "http-body", 967 | "hyper", 968 | "hyper-timeout", 969 | "percent-encoding", 970 | "pin-project", 971 | "prost", 972 | "prost-derive", 973 | "tokio", 974 | "tokio-stream", 975 | "tokio-util", 976 | "tower", 977 | "tower-layer", 978 | "tower-service", 979 | "tracing", 980 | "tracing-futures", 981 | ] 982 | 983 | [[package]] 984 | name = "tonic-build" 985 | version = "0.8.0" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "2fbcd2800e34e743b9ae795867d5f77b535d3a3be69fd731e39145719752df8c" 988 | dependencies = [ 989 | "prettyplease", 990 | "proc-macro2", 991 | "prost-build", 992 | "quote", 993 | "syn", 994 | ] 995 | 996 | [[package]] 997 | name = "tower" 998 | version = "0.4.13" 999 | source = "registry+https://github.com/rust-lang/crates.io-index" 1000 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 1001 | dependencies = [ 1002 | "futures-core", 1003 | "futures-util", 1004 | "indexmap", 1005 | "pin-project", 1006 | "pin-project-lite", 1007 | "rand", 1008 | "slab", 1009 | "tokio", 1010 | "tokio-util", 1011 | "tower-layer", 1012 | "tower-service", 1013 | "tracing", 1014 | ] 1015 | 1016 | [[package]] 1017 | name = "tower-http" 1018 | version = "0.3.4" 1019 | source = "registry+https://github.com/rust-lang/crates.io-index" 1020 | checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba" 1021 | dependencies = [ 1022 | "bitflags", 1023 | "bytes", 1024 | "futures-core", 1025 | "futures-util", 1026 | "http", 1027 | "http-body", 1028 | "http-range-header", 1029 | "pin-project-lite", 1030 | "tower", 1031 | "tower-layer", 1032 | "tower-service", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "tower-layer" 1037 | version = "0.3.1" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" 1040 | 1041 | [[package]] 1042 | name = "tower-service" 1043 | version = "0.3.2" 1044 | source = "registry+https://github.com/rust-lang/crates.io-index" 1045 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1046 | 1047 | [[package]] 1048 | name = "tracing" 1049 | version = "0.1.36" 1050 | source = "registry+https://github.com/rust-lang/crates.io-index" 1051 | checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" 1052 | dependencies = [ 1053 | "cfg-if", 1054 | "log", 1055 | "pin-project-lite", 1056 | "tracing-attributes", 1057 | "tracing-core", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "tracing-attributes" 1062 | version = "0.1.22" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" 1065 | dependencies = [ 1066 | "proc-macro2", 1067 | "quote", 1068 | "syn", 1069 | ] 1070 | 1071 | [[package]] 1072 | name = "tracing-core" 1073 | version = "0.1.29" 1074 | source = "registry+https://github.com/rust-lang/crates.io-index" 1075 | checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" 1076 | dependencies = [ 1077 | "once_cell", 1078 | ] 1079 | 1080 | [[package]] 1081 | name = "tracing-futures" 1082 | version = "0.2.5" 1083 | source = "registry+https://github.com/rust-lang/crates.io-index" 1084 | checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" 1085 | dependencies = [ 1086 | "pin-project", 1087 | "tracing", 1088 | ] 1089 | 1090 | [[package]] 1091 | name = "try-lock" 1092 | version = "0.2.3" 1093 | source = "registry+https://github.com/rust-lang/crates.io-index" 1094 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 1095 | 1096 | [[package]] 1097 | name = "unicode-ident" 1098 | version = "1.0.3" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" 1101 | 1102 | [[package]] 1103 | name = "version_check" 1104 | version = "0.9.4" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1107 | 1108 | [[package]] 1109 | name = "want" 1110 | version = "0.3.0" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1113 | dependencies = [ 1114 | "log", 1115 | "try-lock", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "wasi" 1120 | version = "0.11.0+wasi-snapshot-preview1" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1123 | 1124 | [[package]] 1125 | name = "which" 1126 | version = "4.2.5" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" 1129 | dependencies = [ 1130 | "either", 1131 | "lazy_static", 1132 | "libc", 1133 | ] 1134 | 1135 | [[package]] 1136 | name = "winapi" 1137 | version = "0.3.9" 1138 | source = "registry+https://github.com/rust-lang/crates.io-index" 1139 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1140 | dependencies = [ 1141 | "winapi-i686-pc-windows-gnu", 1142 | "winapi-x86_64-pc-windows-gnu", 1143 | ] 1144 | 1145 | [[package]] 1146 | name = "winapi-i686-pc-windows-gnu" 1147 | version = "0.4.0" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1150 | 1151 | [[package]] 1152 | name = "winapi-util" 1153 | version = "0.1.5" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1156 | dependencies = [ 1157 | "winapi", 1158 | ] 1159 | 1160 | [[package]] 1161 | name = "winapi-x86_64-pc-windows-gnu" 1162 | version = "0.4.0" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1165 | 1166 | [[package]] 1167 | name = "windows-sys" 1168 | version = "0.36.1" 1169 | source = "registry+https://github.com/rust-lang/crates.io-index" 1170 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 1171 | dependencies = [ 1172 | "windows_aarch64_msvc", 1173 | "windows_i686_gnu", 1174 | "windows_i686_msvc", 1175 | "windows_x86_64_gnu", 1176 | "windows_x86_64_msvc", 1177 | ] 1178 | 1179 | [[package]] 1180 | name = "windows_aarch64_msvc" 1181 | version = "0.36.1" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 1184 | 1185 | [[package]] 1186 | name = "windows_i686_gnu" 1187 | version = "0.36.1" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 1190 | 1191 | [[package]] 1192 | name = "windows_i686_msvc" 1193 | version = "0.36.1" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 1196 | 1197 | [[package]] 1198 | name = "windows_x86_64_gnu" 1199 | version = "0.36.1" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 1202 | 1203 | [[package]] 1204 | name = "windows_x86_64_msvc" 1205 | version = "0.36.1" 1206 | source = "registry+https://github.com/rust-lang/crates.io-index" 1207 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 1208 | --------------------------------------------------------------------------------