TcpStream.recv(): wrap callback in RefCell to allow FnMut
This commit is contained in:
parent
0aa75d3544
commit
b74cc5f3aa
@ -3,7 +3,9 @@
|
||||
//! TODO: implement futures AsyncRead/AsyncWrite/Stream/Sink interfaces
|
||||
|
||||
use core::{
|
||||
cell::RefCell,
|
||||
future::Future,
|
||||
ops::DerefMut,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
@ -108,17 +110,18 @@ impl TcpStream {
|
||||
/// number of bytes it consumed, and a user-defined return value of type R.
|
||||
pub async fn recv<F, R>(&self, f: F) -> Result<R>
|
||||
where
|
||||
F: Fn(&[u8]) -> (usize, R),
|
||||
F: FnMut(&[u8]) -> (usize, R),
|
||||
{
|
||||
struct Recv<'a, F: FnOnce(&[u8]) -> (usize, R), R> {
|
||||
struct Recv<'a, F: FnMut(&[u8]) -> (usize, R), R> {
|
||||
stream: &'a TcpStream,
|
||||
f: F,
|
||||
f: RefCell<F>,
|
||||
}
|
||||
|
||||
impl<'a, F: Fn(&[u8]) -> (usize, R), R> Future for Recv<'a, F, R> {
|
||||
impl<'a, F: FnMut(&[u8]) -> (usize, R), R> Future for Recv<'a, F, R> {
|
||||
type Output = Result<R>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let mut f = self.f.borrow_mut();
|
||||
let result = self.stream.with_socket(|mut socket| {
|
||||
if socket_is_handhshaking(&socket) {
|
||||
return Ok(Poll::Pending);
|
||||
@ -126,7 +129,7 @@ impl TcpStream {
|
||||
|
||||
socket.recv(|buf| {
|
||||
if buf.len() > 0 {
|
||||
let (amount, result) = (self.f)(buf);
|
||||
let (amount, result) = (f.deref_mut())(buf);
|
||||
assert!(amount > 0);
|
||||
(amount, Poll::Ready(Ok(result)))
|
||||
} else {
|
||||
@ -150,7 +153,7 @@ impl TcpStream {
|
||||
|
||||
Recv {
|
||||
stream: self,
|
||||
f,
|
||||
f: RefCell::new(f),
|
||||
}.await
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user