1use alloc::boxed::Box;
20use alloc::string::String;
21use alloc::vec::Vec;
22use core::future::Future;
23
24use super::{BoxFut, Connection, Dialer, Listener, PeerInfo, TransportError, TransportResult};
25
26pub type IoError = TransportError;
31
32pub trait ByteRead {
38 fn read<'a>(
40 &'a mut self,
41 buf: &'a mut [u8],
42 ) -> impl Future<Output = TransportResult<usize>> + Send + 'a;
43}
44
45pub trait ByteWrite {
47 fn write_all<'a>(
49 &'a mut self,
50 buf: &'a [u8],
51 ) -> impl Future<Output = TransportResult<()>> + Send + 'a;
52
53 fn flush(&mut self) -> impl Future<Output = TransportResult<()>> + Send + '_;
55}
56
57pub trait ByteStream {
74 fn read<'a>(
76 &'a mut self,
77 buf: &'a mut [u8],
78 ) -> impl Future<Output = TransportResult<usize>> + Send + 'a;
79
80 fn write_all<'a>(
82 &'a mut self,
83 buf: &'a [u8],
84 ) -> impl Future<Output = TransportResult<()>> + Send + 'a;
85
86 fn flush(&mut self) -> impl Future<Output = TransportResult<()>> + Send + '_;
88
89 fn split(&mut self) -> (impl ByteRead + Send + '_, impl ByteWrite + Send + '_);
95}
96
97pub trait StreamDialer {
102 type Stream: ByteStream + Send;
104
105 fn connect<'a>(
108 &'a self,
109 host: &'a str,
110 port: u16,
111 ) -> impl Future<Output = TransportResult<Self::Stream>> + Send + 'a;
112}
113
114pub trait StreamListener {
122 type Stream: ByteStream + Send;
124
125 fn accept(
128 &mut self,
129 ) -> impl Future<Output = TransportResult<(Self::Stream, PeerInfo)>> + Send + '_;
130}
131
132pub trait Datagram {
138 fn send_to<'a>(
140 &'a mut self,
141 buf: &'a [u8],
142 to: core::net::SocketAddr,
143 ) -> impl Future<Output = TransportResult<()>> + Send + 'a;
144
145 fn recv_from<'a>(
147 &'a mut self,
148 buf: &'a mut [u8],
149 ) -> impl Future<Output = TransportResult<(usize, core::net::SocketAddr)>> + Send + 'a;
150
151 fn local_addr(&self) -> Option<core::net::SocketAddr>;
155}
156
157pub trait DatagramBinder {
164 type Socket: Datagram + Send;
166
167 fn bind(&self, port: u16) -> impl Future<Output = TransportResult<Self::Socket>> + Send + '_;
169}
170
171pub trait Delay {
185 fn sleep(&self, d: core::time::Duration) -> impl Future<Output = ()> + Send;
187}
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq)]
199pub enum FrameFault {
200 Recoverable,
202 Fatal,
204}
205
206pub trait Framer {
208 fn encode(&self, frame: &[u8], out: &mut Vec<u8>) -> Result<(), FrameFault>;
213 fn push_bytes(&mut self, bytes: &[u8]);
215 fn next_frame(&mut self) -> Option<Result<Vec<u8>, FrameFault>>;
218}
219
220pub trait FramerFactory {
224 type Framer: Framer + Send;
226 fn framer(&self) -> Self::Framer;
228}
229
230impl<F, T> FramerFactory for F
231where
232 F: Fn() -> T,
233 T: Framer + Send,
234{
235 type Framer = T;
236 fn framer(&self) -> T {
237 self()
238 }
239}
240
241pub struct FramedConnection<S, F, const RC: usize = 256, const WC: usize = 256> {
251 stream: S,
252 framer: F,
253 peer: PeerInfo,
254}
255
256impl<S, F, const RC: usize, const WC: usize> FramedConnection<S, F, RC, WC> {
257 pub fn new(stream: S, framer: F) -> Self {
259 Self {
260 stream,
261 framer,
262 peer: PeerInfo::default(),
263 }
264 }
265
266 pub fn with_peer(stream: S, framer: F, peer: PeerInfo) -> Self {
268 Self {
269 stream,
270 framer,
271 peer,
272 }
273 }
274}
275
276impl<S, F, const RC: usize, const WC: usize> Connection for FramedConnection<S, F, RC, WC>
277where
278 S: ByteStream + Send,
279 F: Framer + Send,
280{
281 fn recv(&mut self) -> BoxFut<'_, TransportResult<Option<Vec<u8>>>> {
282 Box::pin(async move {
283 loop {
284 match self.framer.next_frame() {
285 Some(Ok(frame)) => return Ok(Some(frame)),
286 Some(Err(FrameFault::Recoverable)) => continue,
289 Some(Err(FrameFault::Fatal)) => {
292 log_warn!("framed recv: unrecoverable framing error, closing connection");
293 return Err(TransportError::Framing);
294 }
295 None => {}
296 }
297 let mut chunk = [0u8; RC];
298 match self.stream.read(&mut chunk).await {
299 Ok(0) => return Ok(None), Ok(n) => self.framer.push_bytes(&chunk[..n]),
301 Err(e) => return Err(e),
302 }
303 }
304 })
305 }
306
307 fn send<'a>(&'a mut self, frame: &'a [u8]) -> BoxFut<'a, TransportResult<()>> {
308 Box::pin(async move {
309 let mut out = Vec::new();
310 if let Err(_fault) = self.framer.encode(frame, &mut out) {
311 log_warn!(
312 "framed send: framer rejected a {}-byte frame ({:?}), closing connection",
313 frame.len(),
314 _fault
315 );
316 return Err(TransportError::Framing);
317 }
318 for chunk in out.chunks(WC) {
319 self.stream.write_all(chunk).await?;
320 }
321 self.stream.flush().await
322 })
323 }
324
325 fn peer(&self) -> &PeerInfo {
326 &self.peer
327 }
328}
329
330#[derive(Clone)]
335pub struct FramingDialer<D, FF, const RC: usize = 256, const WC: usize = 256> {
336 dialer: D,
337 framers: FF,
338 host: String,
339 port: u16,
340}
341
342impl<D, FF, const RC: usize, const WC: usize> FramingDialer<D, FF, RC, WC> {
343 pub fn new(dialer: D, framers: FF, host: impl Into<String>, port: u16) -> Self {
346 Self {
347 dialer,
348 framers,
349 host: host.into(),
350 port,
351 }
352 }
353}
354
355impl<D, FF, const RC: usize, const WC: usize> Dialer for FramingDialer<D, FF, RC, WC>
356where
357 D: StreamDialer + Send + Sync,
358 FF: FramerFactory + Send + Sync,
359 D::Stream: 'static,
360 FF::Framer: 'static,
361{
362 fn connect(&self) -> BoxFut<'_, TransportResult<Box<dyn Connection>>> {
363 Box::pin(async move {
364 let stream = self.dialer.connect(&self.host, self.port).await?;
365 let conn: FramedConnection<D::Stream, FF::Framer, RC, WC> =
366 FramedConnection::new(stream, self.framers.framer());
367 Ok(Box::new(conn) as Box<dyn Connection>)
368 })
369 }
370}
371
372pub struct FramingListener<L, FF, const RC: usize = 256, const WC: usize = 256> {
375 listener: L,
376 framers: FF,
377}
378
379impl<L, FF, const RC: usize, const WC: usize> FramingListener<L, FF, RC, WC> {
380 pub fn new(listener: L, framers: FF) -> Self {
383 Self { listener, framers }
384 }
385}
386
387impl<L, FF, const RC: usize, const WC: usize> Listener for FramingListener<L, FF, RC, WC>
388where
389 L: StreamListener + Send,
390 FF: FramerFactory + Send,
391 L::Stream: 'static,
392 FF::Framer: 'static,
393{
394 fn accept(&mut self) -> BoxFut<'_, TransportResult<Box<dyn Connection>>> {
395 Box::pin(async move {
396 let (stream, peer) = self.listener.accept().await?;
397 let conn: FramedConnection<L::Stream, FF::Framer, RC, WC> =
398 FramedConnection::with_peer(stream, self.framers.framer(), peer);
399 Ok(Box::new(conn) as Box<dyn Connection>)
400 })
401 }
402}
403
404pub struct OneShot<T> {
419 inner: spin::Mutex<Option<T>>,
420}
421
422impl<T> OneShot<T> {
423 pub fn new(value: T) -> Self {
425 Self {
426 inner: spin::Mutex::new(Some(value)),
427 }
428 }
429
430 pub fn take(&self) -> Option<T> {
432 self.inner.lock().take()
433 }
434}
435
436impl<T> Default for OneShot<T> {
437 fn default() -> Self {
439 Self {
440 inner: spin::Mutex::new(None),
441 }
442 }
443}
444
445impl<T> From<T> for OneShot<T> {
446 fn from(value: T) -> Self {
447 Self::new(value)
448 }
449}
450
451pub struct OneShotDialer<C> {
458 conn: OneShot<C>,
459}
460
461impl<C> OneShotDialer<C> {
462 pub fn new(conn: C) -> Self {
464 Self {
465 conn: OneShot::new(conn),
466 }
467 }
468}
469
470impl<C: Connection + 'static> Dialer for OneShotDialer<C> {
471 fn connect(&self) -> BoxFut<'_, TransportResult<Box<dyn Connection>>> {
472 Box::pin(async move {
473 self.conn
474 .take()
475 .map(|c| Box::new(c) as Box<dyn Connection>)
476 .ok_or(TransportError::Closed)
477 })
478 }
479}
480
481pub struct OneShotListener<C> {
487 conn: OneShot<C>,
488}
489
490impl<C> OneShotListener<C> {
491 pub fn new(conn: C) -> Self {
493 Self {
494 conn: OneShot::new(conn),
495 }
496 }
497}
498
499impl<C: Connection + 'static> Listener for OneShotListener<C> {
500 fn accept(&mut self) -> BoxFut<'_, TransportResult<Box<dyn Connection>>> {
501 Box::pin(async move {
502 match self.conn.take() {
503 Some(c) => Ok(Box::new(c) as Box<dyn Connection>),
504 None => core::future::pending().await,
505 }
506 })
507 }
508}
509
510#[allow(dead_code)]
518fn _generic_code_over_the_traits_is_send<D, L, B, T>(
519 dialer: D,
520 mut listener: L,
521 binder: B,
522 delay: T,
523) -> BoxFut<'static, ()>
524where
525 D: StreamDialer + Send + 'static,
526 L: StreamListener + Send + 'static,
527 B: DatagramBinder + Send + 'static,
528 T: Delay + Send + 'static,
529{
530 Box::pin(async move {
531 let mut buf = [0u8; 16];
532
533 if let Ok(mut stream) = dialer.connect("example.test", 1883).await {
534 let _ = stream.read(&mut buf).await;
535 let _ = stream.write_all(&buf).await;
536 let _ = stream.flush().await;
537 }
538 if let Ok((mut stream, _peer)) = listener.accept().await {
539 let _ = stream.read(&mut buf).await;
540 }
541 if let Ok(mut socket) = binder.bind(0).await {
542 let _ = socket.recv_from(&mut buf).await;
543 let _ = socket.local_addr();
544 }
545 delay.sleep(core::time::Duration::from_millis(1)).await;
546 })
547}
548
549#[allow(dead_code)]
551fn _one_shot_is_send_sync_without_unsafe() {
552 fn assert_send_sync<T: Send + Sync>() {}
553 assert_send_sync::<OneShot<Vec<u8>>>();
554}
555
556#[cfg(test)]
557mod tests {
558 use super::*;
559 use alloc::sync::Arc;
560 use alloc::vec;
561
562 #[derive(Default)]
569 struct LenFramer {
570 buf: Vec<u8>,
571 }
572
573 impl Framer for LenFramer {
574 fn encode(&self, frame: &[u8], out: &mut Vec<u8>) -> Result<(), FrameFault> {
575 if frame.len() >= 0xFE {
576 return Err(FrameFault::Recoverable);
577 }
578 out.push(frame.len() as u8);
579 out.extend_from_slice(frame);
580 Ok(())
581 }
582 fn push_bytes(&mut self, bytes: &[u8]) {
583 self.buf.extend_from_slice(bytes);
584 }
585 fn next_frame(&mut self) -> Option<Result<Vec<u8>, FrameFault>> {
586 let len = *self.buf.first()? as usize;
587 if len == 0xFF {
588 self.buf.remove(0);
589 return Some(Err(FrameFault::Recoverable));
590 }
591 if len == 0xFE {
592 self.buf.clear();
593 return Some(Err(FrameFault::Fatal));
594 }
595 if self.buf.len() < len + 1 {
596 return None;
597 }
598 let frame = self.buf[1..len + 1].to_vec();
599 self.buf.drain(..len + 1);
600 Some(Ok(frame))
601 }
602 }
603
604 #[derive(Default)]
607 struct StreamState {
608 reads: Vec<Vec<u8>>,
610 written: Vec<u8>,
612 write_sizes: Vec<usize>,
614 flushes: usize,
615 }
616
617 #[derive(Clone, Default)]
618 struct MockStream(Arc<spin::Mutex<StreamState>>);
619
620 impl MockStream {
621 fn with_reads(reads: Vec<Vec<u8>>) -> Self {
622 Self(Arc::new(spin::Mutex::new(StreamState {
623 reads,
624 ..Default::default()
625 })))
626 }
627 }
628
629 impl ByteStream for MockStream {
633 async fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> TransportResult<usize> {
634 let mut st = self.0.lock();
635 if st.reads.is_empty() {
636 return Ok(0);
637 }
638 let chunk = st.reads.remove(0);
639 let n = chunk.len().min(buf.len());
640 buf[..n].copy_from_slice(&chunk[..n]);
641 Ok(n)
642 }
643
644 async fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> TransportResult<()> {
645 let mut st = self.0.lock();
646 st.written.extend_from_slice(buf);
647 st.write_sizes.push(buf.len());
648 Ok(())
649 }
650
651 async fn flush(&mut self) -> TransportResult<()> {
652 self.0.lock().flushes += 1;
653 Ok(())
654 }
655
656 fn split(&mut self) -> (impl ByteRead + Send + '_, impl ByteWrite + Send + '_) {
657 (MockHalf(self.clone()), MockHalf(self.clone()))
658 }
659 }
660
661 struct MockHalf(MockStream);
664
665 impl ByteRead for MockHalf {
666 async fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> TransportResult<usize> {
667 ByteStream::read(&mut self.0, buf).await
668 }
669 }
670
671 impl ByteWrite for MockHalf {
672 async fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> TransportResult<()> {
673 ByteStream::write_all(&mut self.0, buf).await
674 }
675
676 async fn flush(&mut self) -> TransportResult<()> {
677 ByteStream::flush(&mut self.0).await
678 }
679 }
680
681 struct FailingStream;
684
685 impl ByteStream for FailingStream {
686 async fn read<'a>(&'a mut self, _buf: &'a mut [u8]) -> TransportResult<usize> {
687 Err(TransportError::Closed)
688 }
689 async fn write_all<'a>(&'a mut self, _buf: &'a [u8]) -> TransportResult<()> {
690 Err(TransportError::Closed)
691 }
692 async fn flush(&mut self) -> TransportResult<()> {
693 Ok(())
694 }
695 fn split(&mut self) -> (impl ByteRead + Send + '_, impl ByteWrite + Send + '_) {
696 (FailingHalf, FailingHalf)
697 }
698 }
699
700 struct FailingHalf;
702
703 impl ByteRead for FailingHalf {
704 async fn read<'a>(&'a mut self, _buf: &'a mut [u8]) -> TransportResult<usize> {
705 Err(TransportError::Closed)
706 }
707 }
708
709 impl ByteWrite for FailingHalf {
710 async fn write_all<'a>(&'a mut self, _buf: &'a [u8]) -> TransportResult<()> {
711 Err(TransportError::Closed)
712 }
713
714 async fn flush(&mut self) -> TransportResult<()> {
715 Ok(())
716 }
717 }
718
719 #[derive(Clone, Default)]
722 struct DuplexMock {
723 written: Arc<spin::Mutex<Vec<u8>>>,
724 wrote: Arc<tokio::sync::Notify>,
725 }
726
727 impl ByteStream for DuplexMock {
728 async fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> TransportResult<usize> {
729 self.wrote.notified().await;
730 let written = self.written.lock();
731 let n = written.len().min(buf.len());
732 buf[..n].copy_from_slice(&written[..n]);
733 Ok(n)
734 }
735
736 async fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> TransportResult<()> {
737 self.written.lock().extend_from_slice(buf);
738 self.wrote.notify_one();
739 Ok(())
740 }
741
742 async fn flush(&mut self) -> TransportResult<()> {
743 Ok(())
744 }
745
746 fn split(&mut self) -> (impl ByteRead + Send + '_, impl ByteWrite + Send + '_) {
747 (DuplexHalf(self.clone()), DuplexHalf(self.clone()))
748 }
749 }
750
751 struct DuplexHalf(DuplexMock);
753
754 impl ByteRead for DuplexHalf {
755 async fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> TransportResult<usize> {
756 ByteStream::read(&mut self.0, buf).await
757 }
758 }
759
760 impl ByteWrite for DuplexHalf {
761 async fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> TransportResult<()> {
762 ByteStream::write_all(&mut self.0, buf).await
763 }
764
765 async fn flush(&mut self) -> TransportResult<()> {
766 ByteStream::flush(&mut self.0).await
767 }
768 }
769
770 struct MockDialer(MockStream);
771
772 impl StreamDialer for MockDialer {
773 type Stream = MockStream;
774 async fn connect<'a>(&'a self, _host: &'a str, _port: u16) -> TransportResult<MockStream> {
775 Ok(self.0.clone())
776 }
777 }
778
779 struct MockListener(Option<MockStream>);
780
781 impl StreamListener for MockListener {
782 type Stream = MockStream;
783 async fn accept(&mut self) -> TransportResult<(MockStream, PeerInfo)> {
784 let s = self.0.take().ok_or(TransportError::Closed)?;
785 let peer = PeerInfo {
786 peer_addr: Some("10.0.0.1:5555".into()),
787 ..Default::default()
788 };
789 Ok((s, peer))
790 }
791 }
792
793 fn framed(stream: MockStream) -> FramedConnection<MockStream, LenFramer, 256, 256> {
794 FramedConnection::new(stream, LenFramer::default())
795 }
796
797 #[tokio::test]
800 async fn recv_yields_each_frame_then_eof() {
801 let mut conn = framed(MockStream::with_reads(vec![vec![
802 2, b'h', b'i', 3, b'y', b'e', b's',
803 ]]));
804 assert_eq!(conn.recv().await.unwrap(), Some(b"hi".to_vec()));
805 assert_eq!(conn.recv().await.unwrap(), Some(b"yes".to_vec()));
806 assert_eq!(conn.recv().await.unwrap(), None, "closed peer is Ok(None)");
807 }
808
809 #[tokio::test]
810 async fn recv_reassembles_a_frame_split_across_reads() {
811 let mut conn = framed(MockStream::with_reads(vec![
812 vec![3, b'a'],
813 vec![b'b'],
814 vec![b'c'],
815 ]));
816 assert_eq!(conn.recv().await.unwrap(), Some(b"abc".to_vec()));
817 }
818
819 #[tokio::test]
820 async fn recv_skips_a_corrupt_run_and_resyncs() {
821 let mut conn = framed(MockStream::with_reads(vec![vec![
822 0xFF, 0xFF, 2, b'o', b'k',
823 ]]));
824 assert_eq!(
825 conn.recv().await.unwrap(),
826 Some(b"ok".to_vec()),
827 "a run that fails to decode is skipped, not fatal"
828 );
829 }
830
831 #[tokio::test]
832 async fn recv_closes_on_an_unrecoverable_framing_error() {
833 let mut conn = framed(MockStream::with_reads(vec![vec![0xFE, 2, b'o', b'k']]));
836 assert_eq!(
837 conn.recv().await,
838 Err(TransportError::Framing),
839 "a fatal fault ends the connection, it is not skipped"
840 );
841 }
842
843 #[tokio::test]
844 async fn send_reports_a_frame_the_framer_rejects() {
845 let stream = MockStream::default();
846 let mut conn = framed(stream.clone());
847 let oversized = vec![b'x'; 0xFE];
848
849 assert_eq!(
850 conn.send(&oversized).await,
851 Err(TransportError::Framing),
852 "a dropped frame is an error, never a silent Ok"
853 );
854 let st = stream.0.lock();
855 assert!(
856 st.written.is_empty(),
857 "nothing half-encoded reaches the wire"
858 );
859 assert_eq!(st.flushes, 0);
860 }
861
862 #[tokio::test]
863 async fn recv_propagates_the_streams_own_error() {
864 let mut conn = FramedConnection::<_, _, 256, 256>::new(FailingStream, LenFramer::default());
865 assert_eq!(
866 conn.recv().await,
867 Err(TransportError::Closed),
868 "the stream classifies the failure; framing must not flatten it"
869 );
870 }
871
872 #[tokio::test]
873 async fn send_encodes_then_flushes() {
874 let stream = MockStream::default();
875 let mut conn = framed(stream.clone());
876 conn.send(b"hi").await.unwrap();
877
878 let st = stream.0.lock();
879 assert_eq!(st.written, vec![2, b'h', b'i']);
880 assert_eq!(st.flushes, 1);
881 }
882
883 #[tokio::test]
884 async fn send_splits_a_frame_larger_than_the_write_chunk() {
885 let stream = MockStream::default();
886 let mut conn: FramedConnection<MockStream, LenFramer, 256, 4> =
887 FramedConnection::new(stream.clone(), LenFramer::default());
888 conn.send(b"0123456789").await.unwrap();
889
890 let st = stream.0.lock();
891 assert_eq!(st.write_sizes, vec![4, 4, 3], "11 encoded bytes at WC = 4");
892 assert_eq!(st.written.len(), 11);
893 }
894
895 #[tokio::test]
898 async fn framing_dialer_produces_a_working_connection() {
899 let stream = MockStream::with_reads(vec![vec![2, b'h', b'i']]);
900 let dialer: FramingDialer<_, _, 256, 256> =
901 FramingDialer::new(MockDialer(stream), LenFramer::default, "host.test", 1883);
902
903 let mut conn = dialer.connect().await.unwrap();
904 assert_eq!(conn.recv().await.unwrap(), Some(b"hi".to_vec()));
905 }
906
907 #[tokio::test]
908 async fn framing_listener_carries_peer_metadata_through() {
909 let stream = MockStream::with_reads(vec![vec![2, b'h', b'i']]);
910 let mut listener: FramingListener<_, _, 256, 256> =
911 FramingListener::new(MockListener(Some(stream)), LenFramer::default);
912
913 let mut conn = listener.accept().await.unwrap();
914 assert_eq!(conn.peer().peer_addr.as_deref(), Some("10.0.0.1:5555"));
915 assert_eq!(conn.recv().await.unwrap(), Some(b"hi".to_vec()));
916 }
917
918 #[test]
919 fn a_framed_connection_is_boxable_as_dyn_connection() {
920 let conn = framed(MockStream::default());
921 let _boxed: Box<dyn Connection> = Box::new(conn);
922 }
923
924 #[tokio::test]
927 async fn split_halves_run_concurrently() {
928 let mut stream = DuplexMock::default();
929 let (mut rx, mut tx) = stream.split();
930
931 let mut buf = [0u8; 4];
934 let (read, write) = tokio::join!(rx.read(&mut buf), tx.write_all(b"ping"));
935
936 write.expect("write half");
937 assert_eq!(read.expect("read half"), 4);
938 assert_eq!(&buf, b"ping");
939 }
940
941 #[tokio::test]
942 async fn split_halves_address_the_same_stream() {
943 let stream = MockStream::with_reads(vec![b"hi".to_vec()]);
944 let mut split_me = stream.clone();
945 let (mut rx, mut tx) = split_me.split();
946
947 tx.write_all(b"out").await.expect("write half");
948 let mut buf = [0u8; 8];
949 let n = rx.read(&mut buf).await.expect("read half");
950
951 assert_eq!(&buf[..n], b"hi", "the read half drains the stream's reads");
952 assert_eq!(
953 stream.0.lock().written,
954 b"out",
955 "the write half reaches the stream the halves came from"
956 );
957 }
958
959 #[test]
962 fn one_shot_yields_its_value_once() {
963 let cell = OneShot::new(7u32);
964 assert_eq!(cell.take(), Some(7));
965 assert_eq!(cell.take(), None, "a second take must not get the resource");
966 }
967
968 #[test]
969 fn default_one_shot_is_empty() {
970 assert_eq!(OneShot::<u32>::default().take(), None);
971 }
972
973 #[test]
974 fn framer_factory_is_implemented_for_closures() {
975 struct Noop;
976 impl Framer for Noop {
977 fn encode(&self, _frame: &[u8], _out: &mut Vec<u8>) -> Result<(), FrameFault> {
978 Ok(())
979 }
980 fn push_bytes(&mut self, _bytes: &[u8]) {}
981 fn next_frame(&mut self) -> Option<Result<Vec<u8>, FrameFault>> {
982 None
983 }
984 }
985
986 fn takes_factory<FF: FramerFactory>(ff: FF) -> FF::Framer {
987 ff.framer()
988 }
989 let _framer = takes_factory(|| Noop);
990 }
991}