Inital pass at route guide
This commit is contained in:
@@ -1,104 +0,0 @@
|
||||
#![feature(async_await, type_alias_impl_trait)]
|
||||
|
||||
use futures_util::future;
|
||||
use std::future::Future;
|
||||
use std::task::{Context, Poll};
|
||||
use tokio::net::TcpListener;
|
||||
use tonic::{
|
||||
body,
|
||||
server::{Grpc, UnaryService},
|
||||
Request, Response, Status,
|
||||
};
|
||||
use tower_h2::{RecvBody, Server};
|
||||
use tower_service::Service;
|
||||
|
||||
#[derive(Clone, PartialEq, prost::Message)]
|
||||
pub struct HelloRequest {
|
||||
#[prost(string, tag = "1")]
|
||||
pub name: std::string::String,
|
||||
}
|
||||
/// The response message containing the greetings
|
||||
#[derive(Clone, PartialEq, prost::Message)]
|
||||
pub struct HelloReply {
|
||||
#[prost(string, tag = "1")]
|
||||
pub message: std::string::String,
|
||||
}
|
||||
|
||||
struct SayHello;
|
||||
|
||||
impl UnaryService<HelloRequest> for SayHello {
|
||||
type Response = HelloReply;
|
||||
type Future = impl Future<Output = Result<Response<Self::Response>, Status>>;
|
||||
|
||||
fn call(&mut self, request: Request<HelloRequest>) -> Self::Future {
|
||||
async move {
|
||||
println!("REQUEST = {:?}", request);
|
||||
|
||||
let reply = HelloReply {
|
||||
message: "Zomg, it works!".to_string(),
|
||||
};
|
||||
|
||||
Ok(Response::new(reply))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let addr = "[::1]:50051".parse().unwrap();
|
||||
let mut bind = TcpListener::bind(&addr)?;
|
||||
|
||||
let mut server = Server::new(MakeSvc, Default::default());
|
||||
|
||||
while let Ok((sock, _addr)) = bind.accept().await {
|
||||
if let Err(e) = sock.set_nodelay(true) {
|
||||
return Err(e.into());
|
||||
}
|
||||
|
||||
if let Err(e) = server.serve(sock).await {
|
||||
println!("H2 ERROR: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Svc;
|
||||
|
||||
impl Service<http::Request<RecvBody>> for Svc {
|
||||
type Response = http::Response<body::BoxAsyncBody>;
|
||||
type Error = tonic::error::Never;
|
||||
type Future = impl Future<Output = Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Ok(()).into()
|
||||
}
|
||||
|
||||
fn call(&mut self, req: http::Request<RecvBody>) -> Self::Future {
|
||||
let fut = async move {
|
||||
let codec = tonic::codec::ProstCodec::new();
|
||||
let mut grpc = Grpc::new(codec);
|
||||
let response = grpc.unary(SayHello, req).await;
|
||||
Ok(response)
|
||||
};
|
||||
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MakeSvc;
|
||||
|
||||
impl Service<()> for MakeSvc {
|
||||
type Response = Svc;
|
||||
type Error = std::io::Error;
|
||||
type Future = future::Ready<Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Ok(()).into()
|
||||
}
|
||||
|
||||
fn call(&mut self, _: ()) -> Self::Future {
|
||||
future::ok(Svc)
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,7 @@ impl Body for BoxAsyncBody {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: refactor this to accept an !Unpin stream
|
||||
#[derive(Debug)]
|
||||
pub struct AsyncBody<S> {
|
||||
inner: S,
|
||||
|
||||
@@ -43,6 +43,8 @@ pub mod _codegen {
|
||||
|
||||
pub type BoxFuture<T, E> =
|
||||
self::Pin<Box<dyn self::Future<Output = Result<T, E>> + Send + 'static>>;
|
||||
pub type BoxStream<T> =
|
||||
self::Pin<Box<dyn futures_core::Stream<Item = Result<T, crate::Status>> + Send + 'static>>;
|
||||
|
||||
pub mod http {
|
||||
pub use http::*;
|
||||
|
||||
@@ -6,6 +6,10 @@ use tokio_buf::BufStream;
|
||||
use tonic::codec::UnitCodec;
|
||||
use tonic::server::*;
|
||||
use tonic::{Request, Response, Status};
|
||||
use std::pin::Pin;
|
||||
use futures_core::Stream;
|
||||
|
||||
type BoxStream<T> = Pin<Box<dyn Stream<Item = Result<T, Status>> + Send + 'static>>;
|
||||
|
||||
struct SayHello;
|
||||
|
||||
@@ -18,6 +22,18 @@ impl UnaryService<()> for SayHello {
|
||||
}
|
||||
}
|
||||
|
||||
struct SayHelloStream;
|
||||
|
||||
impl<S> ClientStreamingService<S> for SayHelloStream
|
||||
where S: Stream{
|
||||
type Response = ();
|
||||
type Future = impl Future<Output = Result<Response<Self::Response>, Status>>;
|
||||
|
||||
fn call(&mut self, _: Request<S>) -> Self::Future {
|
||||
async move { Ok(Response::new(())) }
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn say_hello() {
|
||||
let codec = UnitCodec::default();
|
||||
@@ -25,6 +41,9 @@ async fn say_hello() {
|
||||
|
||||
let request = http::Request::new(Body(Vec::new()));
|
||||
grpc.unary(SayHello, request).await;
|
||||
|
||||
let request = http::Request::new(Body(Vec::new()));
|
||||
grpc.client_streaming(SayHelloStream, request).await;
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
|
||||
Reference in New Issue
Block a user