I am receiving an error on self.receiver line it says: move occurs because value has type Option<tokio::sync::mpsc::Receiver<Vec<u8>>>, which does not implement the Copy trait`
I am not able to understand why self.tcp is ok but the self.receiver is not ok, also how fix this issue?
tcp is not behind an Option, but receiver is. Therefore, when you write self.tcp.poll_accept(), automatic borrowing can kick in and take a mutable reference to self.tcp. However, Option::unwrap takes the optional by value, which is not possible for something that is behind the reference.
You probably want self.receiver.as_mut().unwrap() in order to convert the by-value optional to a by-mutable-ref optional.
I made some changes by removing the option from receiver ... now I got another error :
Can you help in fixing it and explaining?
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
--> src\main.rs:48:13
|
40 | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
| ---- help: consider changing this to be mutable: `mut self`
...
48 | self.receiver
| ^^^^ cannot borrow as mutable
Another error :
error[E0500]: closure requires unique access to `self` but it is already borrowed
--> src\main.rs:47:46
|
41 | let connection_stream = stream::poll_fn(|cx| {
| ---- borrow occurs here
42 | self.tcp
| ---- first borrow occurs due to use of `self` in closure
...
47 | let message_stream = stream::poll_fn(|cx| {
| ^^^^ closure construction occurs here
48 | self.receiver
| ---- second borrow occurs due to use of `self` in closure
...
54 | match stream::select(connection_stream, message_stream)
| ----------------- first borrow later used her
Thanks, it solves the issue of receiver ... I don't know how I missed that help from the compiler (I am still learning Rust =) )
but again another issue: I am moving context into several closures and the compiler is complaining about it :
error[E0502]: cannot borrow `self` as mutable because it is also borrowed as immutable
--> src\main.rs:50:46
|
44 | let connection_stream = stream::poll_fn(|cx| {
| ---- immutable borrow occurs here
45 | self.tcp
| ---- first borrow occurs due to use of `self` in closure
...
50 | let message_stream = stream::poll_fn(|cx| {
| ^^^^ mutable borrow occurs here
51 | self.receiver
| ---- second borrow occurs due to use of `self` in closure
...
57 | match stream::select(connection_stream, message_stream)
| ----------------- immutable borrow later used here
And when I tried to clone context it self it didn't work .. any suggestion to fix it?
That can't possibly work; it causes two mutable borrows to exist at the same time. You will need to re-think your design. It's hard to tell exactly how without knowing the specific high-level goals of the code.
What I am trying to achieve is creating a stream of data from TCP socket, let me explain:
Accept any new incoming TCP socket (first poll)
After Accepting I need to create a new Tokio task to read the data from the accepted socket then send it back to the stream as Vec<u8> (second poll)
So basically this is how the user will consume the server struct :
let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9090);
let tcp = start_sever(socket).await.unwrap();
read_data(tcp).await.for_each(|data| async move {
println!("{:?}",std::str::from_utf8(&data) );
}).await;
P.S : start_sever fn is just for binding only and creating new TcpListene
I am writing the requirement because ... I think what I am doing totally wrong and maybe there is a better idea from your side ... so please give me some solution.
I generally recommend that you should prefer to use simpler constructs over more complicated ones unless you have a good reason. For example, I generally suggest using loops rather than for_each and just defining an async next method rather than manually implementing Stream.