chore: code format

This commit is contained in:
zawz 2026-05-02 13:54:57 +02:00
parent 25bb724961
commit a9d09e30f8
6 changed files with 318 additions and 263 deletions

View file

@ -1,6 +1,6 @@
use std::time::Duration;
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
pub type RetData = (usize, Option<usize>);
@ -31,12 +31,7 @@ pub fn process_data_ref(dat: &TestData) -> RetData {
pub const DATASIZE: usize = 1000000;
const TEST_STRINGS: [&str; 4] = [
"toto",
"tata",
"titi",
"tutu"
];
const TEST_STRINGS: [&str; 4] = ["toto", "tata", "titi", "tutu"];
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum TestEnum {
@ -54,7 +49,6 @@ use crate::transport::{ClientTransporter,ServerTransporter};
#[rspc::service]
impl TestData {
pub fn len(&self) -> usize {
self.vec.len()
}
@ -102,16 +96,16 @@ pub fn make_test_data(n: usize) -> TestData {
let mut v = Vec::with_capacity(n);
let mut b = true;
for i in 0..n {
v.push(( b ,
v.push((
b,
match i % 3 {
0 => TestEnum::NoValue,
1 => TestEnum::Num(i),
2 => TestEnum::Str(TEST_STRINGS[i % 4].to_string()),
_ => panic!("unexpected error"),
}));
},
));
b = !b;
}
TestData {
vec: v,
}
TestData { vec: v }
}

View file

@ -1,7 +1,8 @@
pub mod data;
use data::{make_test_data,dur_to_str,TestData,TestEnum,TestDataClient,TestDataServer,DATASIZE};
use data::{
dur_to_str, make_test_data, TestData, TestDataClient, TestDataServer, TestEnum, DATASIZE,
};
use tokio::join;
use rspc::transport::serde::TcpClient;
@ -10,7 +11,6 @@ use rspc::transport;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// let t = TcpClient::connect("127.0.0.1:3306").await.unwrap();
// let client = t.spawn().await;
@ -62,7 +62,6 @@ async fn main() -> anyhow::Result<()> {
let now = std::time::Instant::now();
assert_eq!(DATASIZE + 1, client.len().await.unwrap());
println!("len: {}", dur_to_str(now.elapsed()));
};
join!(job1, job2);

View file

@ -1,4 +1,3 @@
extern crate proc_macro;
extern crate quote;
@ -9,8 +8,8 @@ use syn::{
parse::{Parse, ParseStream},
parse_macro_input,
spanned::Spanned,
FnArg, Ident,
Pat, PatType, ReturnType, Visibility, Receiver, ItemImpl, ImplItemFn, ImplItemType, Signature, Attribute,
Attribute, FnArg, Ident, ImplItemFn, ImplItemType, ItemImpl, Pat, PatType, Receiver,
ReturnType, Signature, Visibility,
};
use quote::{format_ident, quote};
@ -63,25 +62,29 @@ struct Service {
}
impl TryFrom<ImplItemFn> for RpcMethod {
type Error = syn::Error;
fn try_from(value: ImplItemFn) -> Result<Self, Self::Error> {
let mut reciever = None;
let mut args = vec!();
let mut args = vec![];
for arg in &value.sig.inputs {
match arg {
FnArg::Typed(captured) if matches!(&*captured.pat, Pat::Ident(_)) => {
args.push(captured.clone());
},
}
FnArg::Typed(captured) => {
return Err(syn::Error::new(captured.pat.span(), "patterns aren't allowed in RPC args"));
},
return Err(syn::Error::new(
captured.pat.span(),
"patterns aren't allowed in RPC args",
));
}
FnArg::Receiver(v) => {
if matches!(v.reference, None) {
return Err(syn::Error::new(v.span(), "self cannot be consumed in RPC method"));
return Err(syn::Error::new(
v.span(),
"self cannot be consumed in RPC method",
));
} else {
reciever = Some(v.clone());
}
@ -105,37 +108,48 @@ impl Parse for Service {
let mut errors = Ok(());
let mut typeitems: Vec<ImplItemType> = vec!();
let fns: Vec<&ImplItemFn> = item.items.iter().filter(|x| {
match x {
let mut typeitems: Vec<ImplItemType> = vec![];
let fns: Vec<&ImplItemFn> = item
.items
.iter()
.filter(|x| match x {
syn::ImplItem::Fn(fnit) => {
matches!(fnit.vis, Visibility::Public(_))
},
}
syn::ImplItem::Type(x) => {
typeitems.push(x.clone());
false
}
_ => false,
}
}).map(|x|
})
.map(|x| {
if let syn::ImplItem::Fn(fnit) = x {
fnit
} else {
unreachable!()
}
).collect();
})
.collect();
let ident = match item.self_ty.as_ref() {
syn::Type::Path(x) => {
match x.path.get_ident() {
syn::Type::Path(x) => match x.path.get_ident() {
Some(i) => i.clone(),
None => return Err(syn::Error::new(x.span(), "generics and paths are not supported")),
None => {
return Err(syn::Error::new(
x.span(),
"generics and paths are not supported",
))
}
},
_ => return Err(syn::Error::new(item.self_ty.span(), "unsupported self type")),
_ => {
return Err(syn::Error::new(
item.self_ty.span(),
"unsupported self type",
))
}
};
let mut rpcs = vec!();
let mut rpcs = vec![];
for one_fn in fns {
match RpcMethod::try_from(one_fn.clone()) {
Ok(v) => rpcs.push(v),
@ -157,7 +171,6 @@ impl Parse for Service {
)
)
}
}
errors?;
@ -171,7 +184,6 @@ impl Parse for Service {
}
}
/// Macro used to generate the RSPC Server and Client objects.
#[proc_macro_attribute]
pub fn service(_attr: TokenStream, mut input: TokenStream) -> TokenStream {
@ -188,62 +200,74 @@ pub fn service(_attr: TokenStream, mut input: TokenStream) -> TokenStream {
let server = &format_ident!("{}Server", ident);
let client = &format_ident!("{}Client", ident);
let fn_names: Vec<_> = rpcs.iter().map(|x| {
&x.sig.ident
}).collect();
let fn_names: Vec<_> = rpcs.iter().map(|x| &x.sig.ident).collect();
let fn_names_camel: Vec<_> = fn_names.iter().map(|x| {
Ident::new(&snake_to_upper_camel(&x.unraw().to_string()), x.span())
}).collect();
let fn_names_camel: Vec<_> = fn_names
.iter()
.map(|x| Ident::new(&snake_to_upper_camel(&x.unraw().to_string()), x.span()))
.collect();
let fn_locks: Vec<_> = rpcs.iter().map(|x| {
match x.reciever.as_ref() {
let fn_locks: Vec<_> = rpcs
.iter()
.map(|x| match x.reciever.as_ref() {
Some(rcv) => match &rcv.mutability {
Some(_) => quote!(write()),
None => quote!(read()),
},
None => quote!(read()),
}
}).collect();
})
.collect();
let fn_mut: Vec<_> = rpcs.iter().map(|x| {
match x.reciever.as_ref() {
let fn_mut: Vec<_> = rpcs
.iter()
.map(|x| match x.reciever.as_ref() {
Some(rcv) => match &rcv.mutability {
Some(_) => quote!(mut),
None => quote!(),
},
None => quote!(),
}
}).collect();
})
.collect();
let fn_await: Vec<_> = rpcs.iter().map(|x| {
match &x.sig.asyncness {
let fn_await: Vec<_> = rpcs
.iter()
.map(|x| match &x.sig.asyncness {
Some(_) => quote!(.await),
None => quote!(),
}
}).collect();
})
.collect();
let args: Vec<_> = rpcs.iter().map(|x| {
let args: Vec<_> = rpcs
.iter()
.map(|x| {
let args = &x.args;
quote! { #(#args),* }
}).collect();
})
.collect();
let arg_types: Vec<_> = rpcs.iter().map(|x| {
let arg_types: Vec<_> = rpcs
.iter()
.map(|x| {
let args = x.args.iter().map(|a| &a.ty);
quote! { #(#args),* }
}).collect();
})
.collect();
let arg_idents: Vec<_> = rpcs.iter().map(|x| {
let arg_idents: Vec<_> = rpcs
.iter()
.map(|x| {
let args = x.args.iter().map(|a| &a.pat);
quote! { #(#args),* }
}).collect();
})
.collect();
let outs: Vec<_> = rpcs.iter().map(|x| {
match &x.sig.output {
let outs: Vec<_> = rpcs
.iter()
.map(|x| match &x.sig.output {
ReturnType::Default => quote! {()},
ReturnType::Type(_, t) => quote! {#t},
}
}).collect();
})
.collect();
let t = quote! {

View file

@ -4,8 +4,8 @@ use futures::future::BoxFuture;
use futures::stream::FuturesUnordered;
use futures::{Future, StreamExt};
use thiserror::Error;
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
use tokio::sync::oneshot;
use tokio::sync::mpsc::{self, UnboundedSender, UnboundedReceiver};
use async_trait::async_trait;
@ -23,7 +23,6 @@ pub enum Error {
OneshotRecvError(#[from] oneshot::error::RecvError),
}
#[derive(Clone)]
/// Client endpoint of any channel.
pub struct ChannelClient<T, R> {
@ -78,10 +77,11 @@ where
T: Send + Sync,
R: Send + Sync,
{
pub async fn internal_request(&self, data: T) -> Result<R, Error> {
let (t, r) = oneshot::channel();
self.channel.send( (data, t) ).map_err(|_| Error::ChannelSendError)?;
self.channel
.send((data, t))
.map_err(|_| Error::ChannelSendError)?;
let output = r.await?;
Ok(output)
}
@ -93,7 +93,6 @@ where
T: Send + Sync,
R: Send + Sync,
{
type Error = Error;
async fn request(&self, data: T) -> Result<R, Self::Error> {
@ -107,10 +106,14 @@ where
T: Send + Sync,
R: Send + Sync,
{
type Error = Error;
async fn listen<F, FR, D>(&mut self, handler: F, stop_response: Option<R>, userdata: D) -> Result<(), Self::Error>
async fn listen<F, FR, D>(
&mut self,
handler: F,
stop_response: Option<R>,
userdata: D,
) -> Result<(), Self::Error>
where
FR: Future<Output = Option<R>> + Send,
F: Fn(T, &D) -> FR + Send + Sync,
@ -124,7 +127,7 @@ where
msg.1.send(v).map_err(|_| Error::ChannelRespError)?;
}
break;
},
}
};
}
Ok(())
@ -177,7 +180,12 @@ where
T: Send + Sync,
R: Send + Sync + 'static,
{
async fn internal_listen<F, FR, D>(&mut self, handler: F, stop_response: Option<R>, userdata: D) -> Result<(), Error>
async fn internal_listen<F, FR, D>(
&mut self,
handler: F,
stop_response: Option<R>,
userdata: D,
) -> Result<(), Error>
where
FR: Future<Output = Option<R>> + Send + 'static,
F: Fn(T, &D) -> FR + Send + Sync,
@ -212,12 +220,15 @@ where
}
let results: Vec<_> = pending.collect().await;
results.into_iter().map(|r| -> Result<(), Error> {
results
.into_iter()
.map(|r| -> Result<(), Error> {
match r {
(Some(r), sender) => sender.send(r).map_err(|_| Error::ChannelRespError),
_ => Ok(()),
}
}).collect::<Result<Vec<_>, Error>>()?;
})
.collect::<Result<Vec<_>, Error>>()?;
Ok(())
}
@ -229,10 +240,14 @@ where
T: Send + Sync,
R: Send + Sync + 'static,
{
type Error = Error;
async fn listen<F, FR, D>(&mut self, handler: F, stop_response: Option<R>, userdata: D) -> Result<(), Self::Error>
async fn listen<F, FR, D>(
&mut self,
handler: F,
stop_response: Option<R>,
userdata: D,
) -> Result<(), Self::Error>
where
FR: Future<Output = Option<R>> + Send + 'static,
F: Fn(T, &D) -> FR + Send + Sync,
@ -247,10 +262,7 @@ where
/// This is intended to be used with self-mutable clients to provide immutable clients to it
pub fn new_multiplexer<T, R>() -> (ChannelClient<T, R>, Multiplexer<T, R>) {
let (c, s) = mpsc::unbounded_channel();
(
ChannelClient { channel: c },
Multiplexer { channel: s },
)
(ChannelClient { channel: c }, Multiplexer { channel: s })
}
pub struct Multiplexer<T, R> {
@ -270,7 +282,13 @@ where
/// - The 3rd party must be handling (usize,T) as input and (usize,R) as output
/// - sender_send(sender) is the function used to send data to the 3rd party
/// - listener_recv(listener) is the function used to recieve data from the 3rd party
pub async fn start<S, SF, L, LF>(mut self, mut sender: S, sender_send: SF, mut listener: L, listener_recv: LF) -> Result<(), Error>
pub async fn start<S, SF, L, LF>(
mut self,
mut sender: S,
sender_send: SF,
mut listener: L,
listener_recv: LF,
) -> Result<(), Error>
where
SF: Fn(&mut S, (usize, T)) -> BoxFuture<bool> + Send + Sync + 'static,
LF: Fn(&mut L) -> BoxFuture<Option<(usize, R)>> + 'static,

View file

@ -1,5 +1,5 @@
use async_trait::async_trait;
use futures::{Future, future::BoxFuture, stream::FuturesUnordered, StreamExt};
use futures::{future::BoxFuture, stream::FuturesUnordered, Future, StreamExt};
pub mod channel;
pub mod serde;
@ -23,22 +23,29 @@ pub trait ClientTransporter<T,R> {
/// - Upon recieving a stop request (handler function return None), server must respond with stop_response if specified to only this request and none other.
/// Finishing and responding to pending jobs is optional.
#[async_trait]
pub trait ServerTransporter<T,R>
{
pub trait ServerTransporter<T, R> {
type Error: std::fmt::Debug;
async fn listen<F, FR, D>(&mut self, handler: F, stop_response: Option<R>, userdata: D) -> Result<(), Self::Error>
async fn listen<F, FR, D>(
&mut self,
handler: F,
stop_response: Option<R>,
userdata: D,
) -> Result<(), Self::Error>
where
FR: Future<Output = Option<R>> + Send + 'static,
F: Fn(T, &D) -> FR + Send + Sync + Copy + 'static,
D: Send + Sync + 'static,
;
D: Send + Sync + 'static;
}
pub
async fn async_listener<T, R, C, L, LF, S, SF, F, FR, D, E>(
listener: &mut L, listener_recv: LF,
sender: &mut S, sender_send: SF,
handler: F, stop_response: Option<R>, userdata: &D) -> Result<(), E>
pub async fn async_listener<T, R, C, L, LF, S, SF, F, FR, D, E>(
listener: &mut L,
listener_recv: LF,
sender: &mut S,
sender_send: SF,
handler: F,
stop_response: Option<R>,
userdata: &D,
) -> Result<(), E>
where
T: Send + Sync,
R: Send + Sync + 'static,
@ -89,7 +96,7 @@ where
match it {
(id, Some(r)) => {
sender_send(sender, (id, r)).await?;
},
}
_ => (),
}
}

View file

@ -1,15 +1,15 @@
use async_trait::async_trait;
use futures::future::BoxFuture;
use thiserror::Error;
use futures::prelude::*;
use serde::{Deserialize, Serialize};
use std::net::Ipv4Addr;
use std::sync::atomic::AtomicUsize;
use thiserror::Error;
use tokio::net::{TcpListener, TcpStream};
//use tokio::net::tcp::{ReadHalf, WriteHalf};
use tokio::io::{ReadHalf, WriteHalf};
use tokio_serde::SymmetricallyFramed;
use tokio_serde::formats::*;
use tokio_serde::SymmetricallyFramed;
use tokio_util::codec::{FramedRead, FramedWrite, LengthDelimitedCodec};
use super::channel::{self, ChannelClient, Multiplexer};
@ -26,18 +26,21 @@ pub enum Error {
type SymmetricalReader<T> = SymmetricallyFramed<
FramedRead<ReadHalf<TcpStream>, LengthDelimitedCodec>,
T,
SymmetricalBincode<T>>;
SymmetricalBincode<T>,
>;
type SymmetricalWriter<T> = SymmetricallyFramed<
FramedWrite<WriteHalf<TcpStream>, LengthDelimitedCodec>,
T,
SymmetricalBincode<T>>;
SymmetricalBincode<T>,
>;
pub struct Receiver<T> {
pub reader: SymmetricalReader<T>,
}
impl<T> Receiver<T> where
impl<T> Receiver<T>
where
SymmetricalReader<T>: TryStream<Ok = T> + Unpin,
{
pub async fn recv(&mut self) -> Result<Option<T>, Error> {
@ -53,32 +56,28 @@ pub struct Sender<T> {
pub writer: SymmetricalWriter<T>,
}
impl<T> Sender<T> where
T: for<'a> Deserialize<'a> + Serialize + Unpin
impl<T> Sender<T>
where
T: for<'a> Deserialize<'a> + Serialize + Unpin,
{
pub async fn send(&mut self, item: T) -> Result<(), Error> {
self.writer.send(item).await.map_err(Error::IO)
}
}
async fn split<T, R>(socket: TcpStream) -> (Sender<(usize, T)>, Receiver<(usize, R)>) {
let (reader, writer) = tokio::io::split(socket);
let reader: FramedRead<
ReadHalf<TcpStream>,
LengthDelimitedCodec,
> = FramedRead::new(reader, LengthDelimitedCodec::new());
let reader: SymmetricalReader<(usize, R)> = SymmetricallyFramed::new(
reader, SymmetricalBincode::default());
let reader: FramedRead<ReadHalf<TcpStream>, LengthDelimitedCodec> =
FramedRead::new(reader, LengthDelimitedCodec::new());
let reader: SymmetricalReader<(usize, R)> =
SymmetricallyFramed::new(reader, SymmetricalBincode::default());
let writer: FramedWrite<
WriteHalf<TcpStream>,
LengthDelimitedCodec,
> = FramedWrite::new(writer, LengthDelimitedCodec::new());
let writer: FramedWrite<WriteHalf<TcpStream>, LengthDelimitedCodec> =
FramedWrite::new(writer, LengthDelimitedCodec::new());
let writer: SymmetricalWriter<(usize, T)> = SymmetricallyFramed::new(
writer, SymmetricalBincode::default());
let writer: SymmetricalWriter<(usize, T)> =
SymmetricallyFramed::new(writer, SymmetricalBincode::default());
(Sender { writer }, Receiver { reader })
}
@ -95,14 +94,12 @@ pub struct TcpServer<T,R> {
ghost: std::marker::PhantomData<(T, R)>,
}
impl<T, R> TcpClient<T, R>
where
T: for<'a> Deserialize<'a> + Serialize + Send + Sync + Unpin + 'static,
R: for<'a> Deserialize<'a> + Serialize + Send + Sync + Unpin + 'static,
{
pub async fn connect<A>(address: &A) ->
Result<TcpClient<T, R>, Error>
pub async fn connect<A>(address: &A) -> Result<TcpClient<T, R>, Error>
where
A: tokio::net::ToSocketAddrs + ?Sized,
{
@ -110,17 +107,28 @@ where
let (sender, receiver) = split(socket).await;
Ok(TcpClient{ sender, receiver, multiplexer: None, req_id: AtomicUsize::new(0), ghost: Default::default() })
Ok(TcpClient {
sender,
receiver,
multiplexer: None,
req_id: AtomicUsize::new(0),
ghost: Default::default(),
})
}
pub async fn multiplex(self) -> (ChannelClient<T,R>, BoxFuture<'static, Result<(), channel::Error>>) {
pub async fn multiplex(
self,
) -> (
ChannelClient<T, R>,
BoxFuture<'static, Result<(), channel::Error>>,
) {
let (client, multiplexer) = channel::new_multiplexer::<T, R>();
let fut = multiplexer.start(
self.sender,
|sender, data| { Box::pin(async {sender.send(data).await.is_ok()}) },
|sender, data| Box::pin(async { sender.send(data).await.is_ok() }),
self.receiver,
|receiver| { Box::pin(async { receiver.recv().await.map_or_else(|_| None, |x| x) }) },
|receiver| Box::pin(async { receiver.recv().await.map_or_else(|_| None, |x| x) }),
);
(client, Box::pin(fut))
@ -133,21 +141,21 @@ where
}
}
impl<T,R> TcpServer<T,R> where
impl<T, R> TcpServer<T, R>
where
T: for<'a> Deserialize<'a> + Serialize,
R: for<'a> Deserialize<'a> + Serialize,
{
pub async fn new(address: &Ipv4Addr, port: u16) ->
Result<TcpServer<T,R>, Error>
{
pub async fn new(address: &Ipv4Addr, port: u16) -> Result<TcpServer<T, R>, Error> {
let address = format!("{}:{}", address, port);
let listener = TcpListener::bind(&address).await.map_err(Error::IO)?;
Ok(TcpServer{ listener, ghost: Default::default() })
Ok(TcpServer {
listener,
ghost: Default::default(),
})
}
async fn accept(&mut self) -> Result<TcpStream, Error>
{
async fn accept(&mut self) -> Result<TcpStream, Error> {
let (socket, address) = self.listener.accept().await.map_err(Error::IO)?;
println!("connection accepted: {:?}", address);
Ok(socket)
@ -162,7 +170,12 @@ where
{
type Error = Error;
async fn listen<F, FR, D>(&mut self, handler: F, stop_response: Option<R>, userdata: D) -> Result<(), Self::Error>
async fn listen<F, FR, D>(
&mut self,
handler: F,
stop_response: Option<R>,
userdata: D,
) -> Result<(), Self::Error>
where
FR: Future<Output = Option<R>> + Send + 'static,
F: Fn(T, &D) -> FR + Send + Sync,