diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 525a32c..8e3662b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,10 +27,10 @@ jobs: with: components: rustfmt, clippy - uses: swatinem/rust-cache@v2 - - name: cargo fmt - run: cargo fmt --all -- --check + - uses: taiki-e/install-action@cargo-make - name: cargo clippy run: cargo clippy --locked --workspace --all-targets --all-features + - run: cargo make format-check test: runs-on: ${{ matrix.target.os }} diff --git a/Cargo.toml b/Cargo.toml index fb01f3f..0ad3729 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "irpc" version = "0.14.0" -edition = "2021" +edition = "2024" authors = ["Rüdiger Klaehn ", "n0 team"] keywords = ["api", "protocol", "network", "rpc"] categories = ["network-programming"] diff --git a/Makefile.toml b/Makefile.toml new file mode 100644 index 0000000..5dde2e7 --- /dev/null +++ b/Makefile.toml @@ -0,0 +1,28 @@ +# Use cargo-make to run tasks here: https://crates.io/crates/cargo-make + +[tasks.format] +workspace = false +command = "cargo" +args = [ + "fmt", + "--all", + "--", + "--config", + "unstable_features=true", + "--config", + "imports_granularity=Crate,group_imports=StdExternalCrate,reorder_imports=true,format_code_in_doc_comments=true", +] + +[tasks.format-check] +workspace = false +command = "cargo" +args = [ + "fmt", + "--all", + "--check", + "--", + "--config", + "unstable_features=true", + "--config", + "imports_granularity=Crate,group_imports=StdExternalCrate,reorder_imports=true,format_code_in_doc_comments=true", +] diff --git a/README.md b/README.md index b959c8b..0b7d864 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ See the [module docs](https://docs.rs/irpc/latest/irpc/). Properly building docs for this crate is quite complex. For all the gory details, see [DOCS.md]. +# Development + +Run `cargo make format` before committing, it will run `cargo fmt` with the arguments expected by this project. + ## License Copyright 2025 N0, INC. diff --git a/examples/compute.rs b/examples/compute.rs index 2ad6192..f6c0c8c 100644 --- a/examples/compute.rs +++ b/examples/compute.rs @@ -6,11 +6,11 @@ use std::{ use anyhow::bail; use futures_buffered::BufferedStreamExt; use irpc::{ + Client, Request, WithChannels, channel::{mpsc, oneshot}, - rpc::{listen, RemoteService}, + rpc::{RemoteService, listen}, rpc_requests, util::{make_client_endpoint, make_server_endpoint}, - Client, Request, WithChannels, }; use n0_future::{ stream::StreamExt, diff --git a/examples/derive.rs b/examples/derive.rs index b629dd4..a6aea40 100644 --- a/examples/derive.rs +++ b/examples/derive.rs @@ -5,11 +5,11 @@ use std::{ use anyhow::{Context, Result}; use irpc::{ + Client, WithChannels, channel::{mpsc, oneshot}, rpc::RemoteService, rpc_requests, util::{make_client_endpoint, make_server_endpoint}, - Client, WithChannels, }; // Import the macro use n0_future::task::{self, AbortOnDropHandle}; diff --git a/examples/local.rs b/examples/local.rs index 3073fa8..57a2c18 100644 --- a/examples/local.rs +++ b/examples/local.rs @@ -6,7 +6,7 @@ use std::collections::BTreeMap; -use irpc::{channel::oneshot, rpc_requests, Client, WithChannels}; +use irpc::{Client, WithChannels, channel::oneshot, rpc_requests}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] diff --git a/examples/storage.rs b/examples/storage.rs index 0f09a6c..9bf73c6 100644 --- a/examples/storage.rs +++ b/examples/storage.rs @@ -5,10 +5,10 @@ use std::{ use anyhow::bail; use irpc::{ + Channels, Client, Request, Service, WithChannels, channel::{mpsc, none::NoReceiver, oneshot}, - rpc::{listen, RemoteService}, + rpc::{RemoteService, listen}, util::{make_client_endpoint, make_server_endpoint}, - Channels, Client, Request, Service, WithChannels, }; use n0_future::task::{self, AbortOnDropHandle}; use serde::{Deserialize, Serialize}; diff --git a/irpc-derive/Cargo.toml b/irpc-derive/Cargo.toml index 072e687..20776dc 100644 --- a/irpc-derive/Cargo.toml +++ b/irpc-derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "irpc-derive" version = "0.11.0" -edition = "2021" +edition = "2024" authors = ["Rüdiger Klaehn "] keywords = ["api", "protocol", "network", "rpc", "macro"] categories = ["network-programming"] diff --git a/irpc-derive/src/lib.rs b/irpc-derive/src/lib.rs index 495854f..9947027 100644 --- a/irpc-derive/src/lib.rs +++ b/irpc-derive/src/lib.rs @@ -2,14 +2,14 @@ use std::collections::HashSet; use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; -use quote::{quote, ToTokens}; +use quote::{ToTokens, quote}; use syn::{ + Attribute, Data, DeriveInput, Error, Fields, Ident, LitStr, Token, Type, Visibility, parse::{Parse, ParseStream}, parse_macro_input, punctuated::Punctuated, spanned::Spanned, token::Comma, - Attribute, Data, DeriveInput, Error, Fields, Ident, LitStr, Token, Type, Visibility, }; /// Attribute on protocol enums and variants @@ -68,7 +68,7 @@ pub fn rpc_requests(attr: TokenStream, item: TokenStream) -> TokenStream { let request_type = match rpc_attr.wrap { None => match &mut variant.fields { - Fields::Unnamed(ref mut fields) if fields.unnamed.len() == 1 => { + Fields::Unnamed(fields) if fields.unnamed.len() == 1 => { fields.unnamed[0].ty.clone() } _ => { @@ -550,8 +550,8 @@ fn single_unnamed_field(ty: Type) -> Fields { fn set_fields_vis(fields: &mut Fields, vis: &Visibility) { let inner = match fields { - Fields::Named(ref mut named) => named.named.iter_mut(), - Fields::Unnamed(ref mut unnamed) => unnamed.unnamed.iter_mut(), + Fields::Named(named) => named.named.iter_mut(), + Fields::Unnamed(unnamed) => unnamed.unnamed.iter_mut(), Fields::Unit => return, }; for field in inner { diff --git a/irpc-iroh/Cargo.toml b/irpc-iroh/Cargo.toml index 63e1988..fd961e2 100644 --- a/irpc-iroh/Cargo.toml +++ b/irpc-iroh/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "irpc-iroh" version = "0.14.0" -edition = "2021" +edition = "2024" authors = ["Rüdiger Klaehn ", "n0 team"] keywords = ["api", "protocol", "network", "rpc"] categories = ["network-programming"] diff --git a/irpc-iroh/examples/0rtt.rs b/irpc-iroh/examples/0rtt.rs index 73451e0..02624af 100644 --- a/irpc-iroh/examples/0rtt.rs +++ b/irpc-iroh/examples/0rtt.rs @@ -9,9 +9,9 @@ use std::{ use anyhow::{Context, Result}; use clap::Parser; use iroh::{ - endpoint::{presets, AfterHandshakeOutcome, ConnectionInfo, EndpointHooks}, - protocol::Router, Endpoint, EndpointAddr, EndpointId, SecretKey, + endpoint::{AfterHandshakeOutcome, ConnectionInfo, EndpointHooks, presets}, + protocol::Router, }; use ping::EchoApi; @@ -232,7 +232,7 @@ mod cli { mod ping { use anyhow::{Context, Result}; use iroh::Endpoint; - use irpc::{channel::oneshot, rpc::RemoteService, rpc_requests, Client, WithChannels}; + use irpc::{Client, WithChannels, channel::oneshot, rpc::RemoteService, rpc_requests}; use irpc_iroh::{ Iroh0RttProtocol, IrohProtocol, IrohRemoteConnection, IrohZrttRemoteConnection, }; diff --git a/irpc-iroh/examples/auth.rs b/irpc-iroh/examples/auth.rs index 7f3014f..208ca7c 100644 --- a/irpc-iroh/examples/auth.rs +++ b/irpc-iroh/examples/auth.rs @@ -4,7 +4,7 @@ //! * Authenticating peers use anyhow::Result; -use iroh::{endpoint::presets, protocol::Router, Endpoint}; +use iroh::{Endpoint, endpoint::presets, protocol::Router}; use self::storage::{StorageClient, StorageServer}; @@ -67,16 +67,17 @@ mod storage { use anyhow::Result; use iroh::{ + Endpoint, endpoint::Connection, protocol::{AcceptError, ProtocolHandler}, - Endpoint, }; use irpc::{ + Client, WithChannels, channel::{mpsc, oneshot}, - rpc_requests, Client, WithChannels, + rpc_requests, }; // Import the macro - use irpc_iroh::{read_request, IrohLazyRemoteConnection}; + use irpc_iroh::{IrohLazyRemoteConnection, read_request}; use serde::{Deserialize, Serialize}; use tracing::info; diff --git a/irpc-iroh/examples/remote-and-local.rs b/irpc-iroh/examples/remote-and-local.rs index aa6c080..ad1f6e9 100644 --- a/irpc-iroh/examples/remote-and-local.rs +++ b/irpc-iroh/examples/remote-and-local.rs @@ -3,7 +3,7 @@ //! The [`StorageApi`] struct is only defined once and can be used both locally and as a remote client. use anyhow::Result; -use iroh::{endpoint::presets, protocol::Router, Endpoint}; +use iroh::{Endpoint, endpoint::presets, protocol::Router}; use self::storage::StorageApi; @@ -71,11 +71,12 @@ mod storage { use std::{collections::BTreeMap, sync::Arc}; use anyhow::{Context, Result}; - use iroh::{protocol::ProtocolHandler, Endpoint}; + use iroh::{Endpoint, protocol::ProtocolHandler}; use irpc::{ + Client, WithChannels, channel::{mpsc, oneshot}, rpc::RemoteService, - rpc_requests, Client, WithChannels, + rpc_requests, }; // Import the macro use irpc_iroh::{IrohLazyRemoteConnection, IrohProtocol}; diff --git a/irpc-iroh/examples/server-actor.rs b/irpc-iroh/examples/server-actor.rs index e2ad174..90b043b 100644 --- a/irpc-iroh/examples/server-actor.rs +++ b/irpc-iroh/examples/server-actor.rs @@ -10,8 +10,8 @@ mod proto { use std::collections::HashMap; use anyhow::Result; - use iroh::{endpoint::presets, protocol::Router, Endpoint, EndpointId}; - use irpc::{channel::oneshot, rpc_requests, Client, WithChannels}; + use iroh::{Endpoint, EndpointId, endpoint::presets, protocol::Router}; + use irpc::{Client, WithChannels, channel::oneshot, rpc_requests}; use irpc_iroh::IrohProtocol; use serde::{Deserialize, Serialize}; @@ -90,7 +90,7 @@ mod cli { use clap::Parser; use iroh::EndpointId; - use crate::proto::{connect, listen, GetRequest, SetRequest}; + use crate::proto::{GetRequest, SetRequest, connect, listen}; #[derive(Debug, Parser)] enum Cli { diff --git a/irpc-iroh/examples/server-shared-state.rs b/irpc-iroh/examples/server-shared-state.rs index bf5b4e0..184fad8 100644 --- a/irpc-iroh/examples/server-shared-state.rs +++ b/irpc-iroh/examples/server-shared-state.rs @@ -2,7 +2,7 @@ //! on the server side instead of with an actor loop. use anyhow::Result; -use iroh::{endpoint::presets, protocol::Router, Endpoint}; +use iroh::{Endpoint, endpoint::presets, protocol::Router}; use self::storage::{StorageClient, StorageServer}; @@ -54,16 +54,17 @@ mod storage { use anyhow::Result; use iroh::{ + Endpoint, endpoint::Connection, protocol::{AcceptError, ProtocolHandler}, - Endpoint, }; use irpc::{ + Client, WithChannels, channel::{mpsc, oneshot}, - rpc_requests, Client, WithChannels, + rpc_requests, }; // Import the macro - use irpc_iroh::{read_request, IrohLazyRemoteConnection, IrohRemoteConnection}; + use irpc_iroh::{IrohLazyRemoteConnection, IrohRemoteConnection, read_request}; use serde::{Deserialize, Serialize}; use tracing::info; diff --git a/irpc-iroh/src/lib.rs b/irpc-iroh/src/lib.rs index 58742d6..b0146b1 100644 --- a/irpc-iroh/src/lib.rs +++ b/irpc-iroh/src/lib.rs @@ -2,31 +2,31 @@ use std::{ fmt, future::Future, io, - sync::{atomic::AtomicU64, Arc}, + sync::{Arc, atomic::AtomicU64}, }; use iroh::{ + EndpointId, endpoint::{ Accepting, Connection, ConnectionError, IncomingZeroRttConnection, OutgoingZeroRttConnection, RecvStream, RemoteEndpointIdError, SendStream, VarInt, ZeroRttStatus, }, protocol::{AcceptError, ProtocolHandler}, - EndpointId, }; use irpc::{ + LocalSender, RequestError, channel::oneshot, rpc::{ - Handler, RemoteConnection, RemoteService, ERROR_CODE_MAX_MESSAGE_SIZE_EXCEEDED, - MAX_MESSAGE_SIZE, + ERROR_CODE_MAX_MESSAGE_SIZE_EXCEEDED, Handler, MAX_MESSAGE_SIZE, RemoteConnection, + RemoteService, }, util::AsyncReadVarintExt, - LocalSender, RequestError, }; -use n0_error::{e, Result}; -use n0_future::{future::Boxed as BoxFuture, TryFutureExt}; +use n0_error::{Result, e}; +use n0_future::{TryFutureExt, future::Boxed as BoxFuture}; use serde::de::DeserializeOwned; -use tracing::{debug, error_span, trace, trace_span, warn, Instrument}; +use tracing::{Instrument, debug, error_span, trace, trace_span, warn}; /// Returns a client that connects to a irpc service using an [`iroh::Endpoint`]. pub fn client( diff --git a/src/lib.rs b/src/lib.rs index f4b2612..3dd3105 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,8 +74,9 @@ //! //! ``` //! use irpc::{ +//! Client, WithChannels, //! channel::{mpsc, oneshot}, -//! rpc_requests, Client, WithChannels, +//! rpc_requests, //! }; //! use serde::{Deserialize, Serialize}; //! @@ -151,7 +152,7 @@ //! quic-rpc, this crate does not abstract over the stream type and is focused //! on [iroh](https://docs.rs/iroh/latest/iroh/index.html) and our [noq](https://docs.rs/noq/latest/noq/index.html). #![cfg_attr(quicrpc_docsrs, feature(doc_cfg))] -use std::{fmt::Debug, future::Future, io, marker::PhantomData, ops::Deref, result}; +use std::{fmt::Debug, future::Future, io, marker::PhantomData, ops::Deref}; /// Processes an RPC request enum and generates trait implementations for use with `irpc`. /// @@ -247,8 +248,9 @@ use std::{fmt::Debug, future::Future, io, marker::PhantomData, ops::Deref, resul /// With `wrap`: /// ``` /// use irpc::{ +/// Client, /// channel::{mpsc, oneshot}, -/// rpc_requests, Client, +/// rpc_requests, /// }; /// use serde::{Deserialize, Serialize}; /// @@ -295,10 +297,10 @@ use std::{fmt::Debug, future::Future, io, marker::PhantomData, ops::Deref, resul #[cfg(feature = "derive")] #[cfg_attr(quicrpc_docsrs, doc(cfg(feature = "derive")))] pub use irpc_derive::rpc_requests; -use n0_error::stack_error; #[cfg(feature = "rpc")] use n0_error::AnyError; -use serde::{de::DeserializeOwned, Serialize}; +use n0_error::stack_error; +use serde::{Serialize, de::DeserializeOwned}; use self::{ channel::{ @@ -498,7 +500,7 @@ pub mod channel { /// /// If this is a boxed sender that represents a remote connection, sending may yield or fail with an io error. /// Local senders will never yield, but can fail if the receiver has been closed. - pub async fn send(self, value: T) -> std::result::Result<(), SendError> { + pub async fn send(self, value: T) -> Result<(), SendError> { match self { Sender::Tokio(tx) => tx.send(value).map_err(|_| e!(SendError::ReceiverClosed)), Sender::Boxed(f) => f(value).await, @@ -569,7 +571,7 @@ pub mod channel { } impl Future for Receiver { - type Output = std::result::Result; + type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut task::Context) -> task::Poll { match self.get_mut() { @@ -814,14 +816,7 @@ pub mod channel { pub trait DynReceiver: Debug + Send + Sync + 'static { fn recv( &mut self, - ) -> Pin< - Box< - dyn Future, RecvError>> - + Send - + Sync - + '_, - >, - >; + ) -> Pin, RecvError>> + Send + Sync + '_>>; } impl Debug for Sender { @@ -846,7 +841,7 @@ pub mod channel { /// then the sender will be closed and further sends will return an [`SendError::Io`] /// with [`std::io::ErrorKind::BrokenPipe`]. Therefore, make sure to always poll the /// future until completion if you want to reuse the sender or any clone afterwards. - pub async fn send(&self, value: T) -> std::result::Result<(), SendError> { + pub async fn send(&self, value: T) -> Result<(), SendError> { match self { Sender::Tokio(tx) => tx .send(value) @@ -877,7 +872,7 @@ pub mod channel { /// then the sender will be closed and further sends will return an [`SendError::Io`] /// with [`std::io::ErrorKind::BrokenPipe`]. Therefore, make sure to always poll the /// future until completion if you want to reuse the sender or any clone afterwards. - pub async fn try_send(&self, value: T) -> std::result::Result { + pub async fn try_send(&self, value: T) -> Result { match self { Sender::Tokio(tx) => match tx.try_send(value) { Ok(()) => Ok(true), @@ -906,7 +901,7 @@ pub mod channel { /// cleanly closed the connection. /// /// Returns an an io error if there was an error receiving the message. - pub async fn recv(&mut self) -> std::result::Result, RecvError> { + pub async fn recv(&mut self) -> Result, RecvError> { match self { Self::Tokio(rx) => Ok(rx.recv().await), Self::Boxed(rx) => Ok(rx.recv().await?), @@ -951,7 +946,7 @@ pub mod channel { #[cfg(feature = "stream")] pub fn into_stream( self, - ) -> impl n0_future::Stream> + Send + Sync + 'static + ) -> impl n0_future::Stream> + Send + Sync + 'static { n0_future::stream::unfold(self, |mut recv| async move { recv.recv().await.transpose().map(|msg| (msg, recv)) @@ -1012,10 +1007,9 @@ pub mod channel { value: U, ) -> Pin> + Send + '_>> { Box::pin(async move { - if let Some(v) = (self.f)(value) { - self.sender.send(v).await - } else { - Ok(()) + match (self.f)(value) { + Some(v) => self.sender.send(v).await, + _ => Ok(()), } }) } @@ -1025,10 +1019,9 @@ pub mod channel { value: U, ) -> Pin> + Send + '_>> { Box::pin(async move { - if let Some(v) = (self.f)(value) { - self.sender.try_send(v).await - } else { - Ok(true) + match (self.f)(value) { + Some(v) => self.sender.try_send(v).await, + _ => Ok(true), } }) } @@ -1071,14 +1064,8 @@ pub mod channel { { fn recv( &mut self, - ) -> Pin< - Box< - dyn Future, RecvError>> - + Send - + Sync - + '_, - >, - > { + ) -> Pin, RecvError>> + Send + Sync + '_>> + { Box::pin(async move { while let Some(msg) = self.receiver.recv().await? { if let Some(v) = (self.f)(msg) { @@ -1347,9 +1334,8 @@ impl Client { #[allow(clippy::type_complexity)] pub fn request( &self, - ) -> impl Future< - Output = result::Result, rpc::RemoteSender>, RequestError>, - > + 'static { + ) -> impl Future, rpc::RemoteSender>, RequestError>> + use + { #[cfg(feature = "rpc")] { let cloned = match &self.0 { @@ -1382,6 +1368,7 @@ impl Client { msg: Req, local_update_cap: usize, ) -> impl Future, oneshot::Receiver)>> + + use where S: From, S::Message: From>, @@ -1417,7 +1404,10 @@ impl Client { msg: Req, local_update_cap: usize, local_response_cap: usize, - ) -> impl Future, mpsc::Receiver)>> + Send + 'static + ) -> impl Future, mpsc::Receiver)>> + + Send + + 'static + + use where S: From, S::Message: From>, @@ -1549,7 +1539,7 @@ impl Client { &self, msg: Req, local_response_cap: usize, - ) -> impl Future>> + Send + 'static + ) -> impl Future>> + Send + 'static + use where S: From, S::Message: From>, @@ -1713,7 +1703,7 @@ pub enum Error { } /// Type alias for a result with an irpc error type. -pub type Result = std::result::Result; +pub type Result = std::result::Result; impl From for io::Error { fn from(e: Error) -> Self { @@ -1793,16 +1783,17 @@ pub mod rpc { use noq::ConnectionError; use serde::de::DeserializeOwned; use smallvec::SmallVec; - use tracing::{debug, error_span, trace, warn, Instrument}; + use tracing::{Instrument, debug, error_span, trace, warn}; use crate::{ + LocalSender, RequestError, RpcMessage, Service, channel::{ + SendError, mpsc::{self, DynReceiver, DynSender}, none::NoSender, - oneshot, SendError, + oneshot, }, - util::{now_or_never, AsyncReadVarintExt, WriteVarintExt}, - LocalSender, RequestError, RpcMessage, Service, + util::{AsyncReadVarintExt, WriteVarintExt, now_or_never}, }; /// Default max message size (16 MiB). @@ -1999,7 +1990,7 @@ pub mod rpc { pub(crate) fn prepare_write( msg: impl Into, - ) -> std::result::Result, WriteError> { + ) -> Result, WriteError> { let msg = msg.into(); if postcard::experimental::serialized_size(&msg)? as u64 > MAX_MESSAGE_SIZE { return Err(e!(WriteError::MaxMessageSizeExceeded)); @@ -2137,14 +2128,8 @@ pub mod rpc { impl DynReceiver for NoqReceiver { fn recv( &mut self, - ) -> Pin< - Box< - dyn Future, mpsc::RecvError>> - + Send - + Sync - + '_, - >, - > { + ) -> Pin, mpsc::RecvError>> + Send + Sync + '_>> + { Box::pin(async { let read = &mut self.recv; let Some(size) = read.read_varint_u64().await? else { @@ -2465,7 +2450,7 @@ impl LocalSender { pub fn send( &self, value: impl Into>, - ) -> impl Future> + Send + 'static + ) -> impl Future> + Send + 'static where T: Channels, S::Message: From>, @@ -2478,7 +2463,7 @@ impl LocalSender { pub fn send_raw( &self, value: S::Message, - ) -> impl Future> + Send + 'static { + ) -> impl Future> + Send + 'static + use { let x = self.0.clone(); async move { x.send(value).await } } diff --git a/src/util.rs b/src/util.rs index 81561d0..865a808 100644 --- a/src/util.rs +++ b/src/util.rs @@ -8,7 +8,7 @@ mod noq_setup_utils { use std::{sync::Arc, time::Duration}; use n0_error::{Result, StdResultExt}; - use noq::{crypto::rustls::QuicClientConfig, ClientConfig, ServerConfig}; + use noq::{ClientConfig, ServerConfig, crypto::rustls::QuicClientConfig}; /// Create a noq client config and trusts given certificates. /// @@ -189,7 +189,7 @@ mod varint_util { io::{self, Error}, }; - use serde::{de::DeserializeOwned, Serialize}; + use serde::{Serialize, de::DeserializeOwned}; use smallvec::SmallVec; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; @@ -219,13 +219,13 @@ mod varint_util { // Read a single byte let res = reader.read_u8().await; - if shift == 0 { - if let Err(cause) = res { - if cause.kind() == io::ErrorKind::UnexpectedEof { - return Ok(None); - } else { - return Err(cause); - } + if shift == 0 + && let Err(cause) = res + { + if cause.kind() == io::ErrorKind::UnexpectedEof { + return Ok(None); + } else { + return Err(cause); } } diff --git a/tests/mpsc_channel.rs b/tests/mpsc_channel.rs index 017cf27..360d937 100644 --- a/tests/mpsc_channel.rs +++ b/tests/mpsc_channel.rs @@ -7,8 +7,8 @@ use std::{ use irpc::{ channel::{ - mpsc::{self, Receiver, RecvError}, SendError, + mpsc::{self, Receiver, RecvError}, }, util::AsyncWriteVarintExt, }; diff --git a/tests/oneshot_channel.rs b/tests/oneshot_channel.rs index 1aec4a4..d1f57ae 100644 --- a/tests/oneshot_channel.rs +++ b/tests/oneshot_channel.rs @@ -4,8 +4,8 @@ use std::io::{self, ErrorKind}; use irpc::{ channel::{ - oneshot::{self, RecvError}, SendError, + oneshot::{self, RecvError}, }, util::AsyncWriteVarintExt, };