Skip to content

Commit

Permalink
feat: use afit and rpitit to optimize Service trait
Browse files Browse the repository at this point in the history
  • Loading branch information
PureWhiteWu committed Oct 19, 2023
1 parent 18fdd56 commit 0209838
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 137 deletions.
5 changes: 4 additions & 1 deletion motore-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ proc-macro2 = "1"
quote = "1"
syn = { version = "1", features = ["full"] }


[dev-dependencies]
motore = { path = "../motore" }

[features]
default = []
service_send = []
32 changes: 20 additions & 12 deletions motore-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ pub fn service(_args: TokenStream, input: TokenStream) -> TokenStream {
}

fn expand(item: &mut ItemImpl) -> Result<(), syn::Error> {
let generic_params = &item.generics.params;
let generic_params: &syn::punctuated::Punctuated<syn::GenericParam, syn::token::Comma> =
&item.generics.params;
let call_method = item
.items
.iter_mut()
Expand Down Expand Up @@ -89,7 +90,7 @@ fn expand(item: &mut ItemImpl) -> Result<(), syn::Error> {
}
};

let cx_is_generic = generic_params
let _cx_is_generic = generic_params
.iter()
.filter_map(|p| match p {
syn::GenericParam::Type(t) => Some(t),
Expand Down Expand Up @@ -128,9 +129,16 @@ fn expand(item: &mut ItemImpl) -> Result<(), syn::Error> {
}
};
sig.asyncness = None;
sig.generics = parse_quote!(<'cx, 's>);
sig.generics.where_clause = Some(parse_quote!(where 's: 'cx));
sig.output = parse_quote!(-> Self::Future<'cx>);
sig.generics = parse_quote!(<'s, 'cx>);
// sig.generics.where_clause = Some(parse_quote!(where 's: 'cx));
#[cfg(feature = "service_send")]
{
sig.output = parse_quote!(-> impl ::std::future::Future<Output = Result<Self::Response, Self::Error>> + Send);
}
#[cfg(not(feature = "service_send"))]
{
sig.output = parse_quote!(-> impl ::std::future::Future<Output = Result<Self::Response, Self::Error>>);
}
sig.inputs[0] = parse_quote!(&'s self);
let old_stmts = &call_method.block.stmts;
call_method.block.stmts = vec![parse_quote!(async move { #(#old_stmts)* })];
Expand All @@ -143,14 +151,14 @@ fn expand(item: &mut ItemImpl) -> Result<(), syn::Error> {
type Error = #err_ty;
));

let cx_bound = cx_is_generic.then(|| Some(quote!(Cx: 'cx,))).into_iter();
// let cx_bound = cx_is_generic.then(|| Some(quote!(Cx: 'cx,))).into_iter();

item.items.push(parse_quote!(
type Future<'cx> = impl ::std::future::Future<Output = Result<Self::Response, Self::Error>> + 'cx
where
#(#cx_bound)*
Self:'cx;
));
// item.items.push(parse_quote!(
// type Future<'cx> = impl ::std::future::Future<Output = Result<Self::Response,
// Self::Error>> + 'cx where
// #(#cx_bound)*
// Self:'cx;
// ));

Ok(())
}
2 changes: 2 additions & 0 deletions motore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ tower = { version = "0.4", optional = true }
http = "0.2"

[features]
default = ["service_send"]
tower = ["dep:tower"]
service_send = ["motore-macros/service_send"]

[package.metadata.docs.rs]
all-features = true
Expand Down
29 changes: 22 additions & 7 deletions motore/src/make/make_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ use crate::{sealed::Sealed, UnaryService};
pub trait MakeConnection<Address>: Sealed<(Address,)> {
type Connection: AsyncRead + AsyncWrite + Unpin + Send;
type Error;
type Future<'s>: Future<Output = Result<Self::Connection, Self::Error>> + Send + 's
where
Self: 's,
Address: 's;

fn make_connection(&self, req: Address) -> Self::Future<'_>;
#[cfg(feature = "service_send")]
fn make_connection(
&self,
req: Address,
) -> impl Future<Output = Result<Self::Connection, Self::Error>> + Send;
#[cfg(not(feature = "service_send"))]
fn make_connection(
&self,
req: Address,
) -> impl Future<Output = Result<Self::Connection, Self::Error>>;
}

impl<S, Address> Sealed<(Address,)> for S where S: UnaryService<Address> {}
Expand All @@ -28,9 +33,19 @@ where
{
type Connection = S::Response;
type Error = S::Error;
type Future<'s> = impl Future<Output = Result<Self::Connection, Self::Error>> + Send + 's where Self: 's, Address:'s;

fn make_connection(&self, addr: Address) -> Self::Future<'_> {
#[cfg(feature = "service_send")]
fn make_connection(
&self,
addr: Address,
) -> impl Future<Output = Result<Self::Connection, Self::Error>> + Send {
self.call(addr)
}
#[cfg(not(feature = "service_send"))]
fn make_connection(
&self,
addr: Address,
) -> impl Future<Output = Result<Self::Connection, Self::Error>> {
self.call(addr)
}
}
27 changes: 17 additions & 10 deletions motore/src/service/ext/map_err.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use futures::{Future, TryFutureExt};
use std::future::Future;

use futures::TryFutureExt;

use crate::Service;

Expand All @@ -20,15 +22,20 @@ where

type Error = E;

type Future<'cx> = impl Future<Output = Result<Self::Response, Self::Error>> + 'cx
where
Cx: 'cx,
Self: 'cx;

fn call<'cx, 's>(&'s self, cx: &'cx mut Cx, req: Req) -> Self::Future<'cx>
where
's: 'cx,
{
#[cfg(feature = "service_send")]
fn call<'s, 'cx>(
&'s self,
cx: &'cx mut Cx,
req: Req,
) -> impl Future<Output = Result<Self::Response, Self::Error>> + Send {
self.inner.call(cx, req).map_err(self.f.clone())
}
#[cfg(not(feature = "service_send"))]
fn call<'s, 'cx>(
&'s self,
cx: &'cx mut Cx,
req: Req,
) -> impl Future<Output = Result<Self::Response, Self::Error>> {
self.inner.call(cx, req).map_err(self.f.clone())
}
}
26 changes: 16 additions & 10 deletions motore/src/service/ext/map_response.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt;
use std::{fmt, future::Future};

use futures::{Future, TryFutureExt};
use futures::TryFutureExt;

use crate::Service;
/// Service returned by the [`map_response`] combinator.
Expand All @@ -19,15 +19,21 @@ where
{
type Response = Response;
type Error = S::Error;
type Future<'cx> = impl Future<Output = Result<Self::Response, Self::Error>> + 'cx
where
Cx: 'cx,
Self: 'cx;

fn call<'cx, 's>(&'s self, cx: &'cx mut Cx, req: Req) -> Self::Future<'cx>
where
's: 'cx,
{
#[cfg(feature = "service_send")]
fn call<'s, 'cx>(
&'s self,
cx: &'cx mut Cx,
req: Req,
) -> impl Future<Output = Result<Self::Response, Self::Error>> + Send {
self.inner.call(cx, req).map_ok(self.f.clone())
}
#[cfg(not(feature = "service_send"))]
fn call<'s, 'cx>(
&'s self,
cx: &'cx mut Cx,
req: Req,
) -> impl Future<Output = Result<Self::Response, Self::Error>> {
self.inner.call(cx, req).map_ok(self.f.clone())
}
}
Expand Down
Loading

0 comments on commit 0209838

Please sign in to comment.