1- use core:: cell:: RefCell ;
2-
1+ use embassy_sync:: { blocking_mutex:: raw:: RawMutex , mutex:: Mutex } ;
32use embedded_io_async:: { Read , Write } ;
43use framez:: {
54 Framed ,
65 state:: { ReadState , ReadWriteState , WriteState } ,
76} ;
7+ use futures:: { Sink , Stream } ;
88use rand:: RngCore ;
99
1010use crate :: {
1111 FragmentsState , Frame , FramesCodec , Message , OnFrame , OwnedMessage , WebSocketCore ,
1212 error:: { Error , ProtocolError } ,
1313 http:: { Request , Response } ,
14- next,
1514 options:: { AcceptOptions , ConnectOptions } ,
1615} ;
1716
@@ -309,6 +308,16 @@ impl<'buf, RW, Rng> WebSocket<'buf, RW, Rng> {
309308 pub const fn caller ( & self ) -> crate :: functions:: ReadAutoCaller {
310309 crate :: functions:: ReadAutoCaller
311310 }
311+
312+ /// TODO
313+ pub fn owned < const N : usize , M > ( self ) -> OwnedWebSocket < ' buf , N , RW , Rng , M >
314+ where
315+ M : RawMutex ,
316+ {
317+ OwnedWebSocket {
318+ inner : Mutex :: new ( self ) ,
319+ }
320+ }
312321}
313322
314323/// Read half of a WebSocket connection.
@@ -465,28 +474,25 @@ impl<'buf, RW, Rng> WebSocketWrite<'buf, RW, Rng> {
465474}
466475
467476#[ derive( Debug ) ]
468- pub struct OwnedWebSocket < ' buf , const N : usize , RW , Rng > {
469- // XXX: the idea of the refcell is to have a stream and a sink at the same time using the same core
470- // but this would panic when using select on the stream and then using the sink to send a message, because the stream would have a mutable reference to the core and then the sink would try to borrow it again.
471- // See clippy warning
472- // I think we can only have a stream or a sink at a time, mutably borrowing the core
473- core : RefCell < WebSocket < ' buf , RW , Rng > > ,
477+ pub struct OwnedWebSocket < ' buf , const N : usize , RW , Rng , Mtx : RawMutex > {
478+ inner : Mutex < Mtx , WebSocket < ' buf , RW , Rng > > ,
474479}
475480
476- impl < ' buf , const N : usize , RW , Rng > OwnedWebSocket < ' buf , N , RW , Rng >
481+ impl < ' buf , const N : usize , RW , Rng , Mtx > OwnedWebSocket < ' buf , N , RW , Rng , Mtx >
477482where
478483 RW : Read + Write ,
479484 Rng : RngCore ,
485+ Mtx : RawMutex ,
480486{
481487 pub async fn next (
482488 & self ,
483489 ) -> Option < Result < Result < OwnedMessage < N > , heapless:: CapacityError > , Error < RW :: Error > > > {
484- let mut websocket = self . core . borrow_mut ( ) ;
490+ let mut websocket = self . inner . lock ( ) . await ;
485491
486492 match ' next: loop {
487493 match websocket
488494 . caller ( )
489- . call_next :: < N , _ , _ , _ > ( websocket. auto ( ) , & mut websocket. core )
495+ . call_owned :: < N , _ , _ , _ > ( websocket. auto ( ) , & mut websocket. core )
490496 . await
491497 {
492498 Some ( Ok ( None ) ) => continue ' next,
@@ -500,4 +506,45 @@ where
500506 Some ( Err ( err) ) => Some ( Err ( err) ) ,
501507 }
502508 }
509+
510+ pub async fn send ( & self , message : Message < ' _ > ) -> Result < ( ) , Error < RW :: Error > > {
511+ let mut websocket = self . inner . lock ( ) . await ;
512+
513+ websocket. send ( message) . await
514+ }
515+
516+ pub fn stream (
517+ & self ,
518+ ) -> impl Stream <
519+ Item = Result < Result < OwnedMessage < N > , heapless:: CapacityError > , Error < RW :: Error > > ,
520+ > + ' _ {
521+ futures:: stream:: unfold ( ( self , false ) , move |( this, errored) | async move {
522+ if errored {
523+ return None ;
524+ }
525+
526+ match this. next ( ) . await {
527+ Some ( Ok ( item) ) => Some ( ( Ok ( item) , ( this, false ) ) ) ,
528+ Some ( Err ( err) ) => Some ( ( Err ( err) , ( this, true ) ) ) ,
529+ None => None ,
530+ }
531+ } )
532+ }
533+
534+ pub fn sink ( & self ) -> impl Sink < Message < ' _ > , Error = Error < RW :: Error > > + ' _ {
535+ futures:: sink:: unfold ( self , |this, item : Message < ' _ > | async move {
536+ this. send ( item) . await ?;
537+
538+ Ok ( this)
539+ } )
540+ }
541+
542+ pub fn split (
543+ & self ,
544+ ) -> (
545+ impl Stream < Item = Result < Result < OwnedMessage < N > , heapless:: CapacityError > , Error < RW :: Error > > > ,
546+ impl Sink < Message < ' _ > , Error = Error < RW :: Error > > ,
547+ ) {
548+ ( self . stream ( ) , self . sink ( ) )
549+ }
503550}
0 commit comments