@@ -22,14 +22,15 @@ pub use futures_lite::AsyncWriteExt;
2222pub use source:: * ;
2323
2424use bevy_utils:: { BoxedFuture , ConditionalSendFuture } ;
25- use futures_io:: { AsyncRead , AsyncSeek , AsyncWrite } ;
25+ use futures_io:: { AsyncRead , AsyncWrite } ;
2626use futures_lite:: { ready, Stream } ;
27+ use std:: task:: Context ;
2728use std:: {
28- io :: SeekFrom ,
29+ mem :: size_of ,
2930 path:: { Path , PathBuf } ,
3031 pin:: Pin ,
3132 sync:: Arc ,
32- task:: { Context , Poll } ,
33+ task:: Poll ,
3334} ;
3435use thiserror:: Error ;
3536
@@ -80,13 +81,51 @@ pub const STACK_FUTURE_SIZE: usize = 10 * size_of::<&()>();
8081
8182pub use stackfuture:: StackFuture ;
8283
84+ /// Asynchronously advances the cursor position by a specified number of bytes.
85+ ///
86+ /// This trait is a simplified version of the [`futures_io::AsyncSeek`] trait, providing
87+ /// support exclusively for the [`futures_io::SeekFrom::Current`] variant. It allows for relative
88+ /// seeking from the current cursor position.
89+ pub trait AsyncSeekForward {
90+ /// Attempts to asynchronously seek forward by a specified number of bytes from the current cursor position.
91+ ///
92+ /// Seeking beyond the end of the stream is allowed and the behavior for this case is defined by the implementation.
93+ /// The new position, relative to the beginning of the stream, should be returned upon successful completion
94+ /// of the seek operation.
95+ ///
96+ /// If the seek operation completes successfully,
97+ /// the new position relative to the beginning of the stream should be returned.
98+ ///
99+ /// # Implementation
100+ ///
101+ /// Implementations of this trait should handle [`Poll::Pending`] correctly, converting
102+ /// [`std::io::ErrorKind::WouldBlock`] errors into [`Poll::Pending`] to indicate that the operation is not
103+ /// yet complete and should be retried, and either internally retry or convert
104+ /// [`std::io::ErrorKind::Interrupted`] into another error kind.
105+ fn poll_seek_forward (
106+ self : Pin < & mut Self > ,
107+ cx : & mut Context < ' _ > ,
108+ offset : u64 ,
109+ ) -> Poll < futures_io:: Result < u64 > > ;
110+ }
111+
112+ impl < T : ?Sized + AsyncSeekForward + Unpin > AsyncSeekForward for Box < T > {
113+ fn poll_seek_forward (
114+ mut self : Pin < & mut Self > ,
115+ cx : & mut Context < ' _ > ,
116+ offset : u64 ,
117+ ) -> Poll < futures_io:: Result < u64 > > {
118+ Pin :: new ( & mut * * self ) . poll_seek_forward ( cx, offset)
119+ }
120+ }
121+
83122/// A type returned from [`AssetReader::read`], which is used to read the contents of a file
84123/// (or virtual file) corresponding to an asset.
85124///
86- /// This is essentially a trait alias for types implementing [`AsyncRead`] and [`AsyncSeek `].
125+ /// This is essentially a trait alias for types implementing [`AsyncRead`] and [`AsyncSeekForward `].
87126/// The only reason a blanket implementation is not provided for applicable types is to allow
88127/// implementors to override the provided implementation of [`Reader::read_to_end`].
89- pub trait Reader : AsyncRead + AsyncSeek + Unpin + Send + Sync {
128+ pub trait Reader : AsyncRead + AsyncSeekForward + Unpin + Send + Sync {
90129 /// Reads the entire contents of this reader and appends them to a vec.
91130 ///
92131 /// # Note for implementors
@@ -556,32 +595,20 @@ impl AsyncRead for VecReader {
556595 }
557596}
558597
559- impl AsyncSeek for VecReader {
560- fn poll_seek (
598+ impl AsyncSeekForward for VecReader {
599+ fn poll_seek_forward (
561600 mut self : Pin < & mut Self > ,
562601 _cx : & mut Context < ' _ > ,
563- pos : SeekFrom ,
602+ offset : u64 ,
564603 ) -> Poll < std:: io:: Result < u64 > > {
565- let result = match pos {
566- SeekFrom :: Start ( offset) => offset. try_into ( ) ,
567- SeekFrom :: End ( offset) => self . bytes . len ( ) . try_into ( ) . map ( |len : i64 | len - offset) ,
568- SeekFrom :: Current ( offset) => self
569- . bytes_read
570- . try_into ( )
571- . map ( |bytes_read : i64 | bytes_read + offset) ,
572- } ;
604+ let result = self
605+ . bytes_read
606+ . try_into ( )
607+ . map ( |bytes_read : u64 | bytes_read + offset) ;
573608
574609 if let Ok ( new_pos) = result {
575- if new_pos < 0 {
576- Poll :: Ready ( Err ( std:: io:: Error :: new (
577- std:: io:: ErrorKind :: InvalidInput ,
578- "seek position is out of range" ,
579- ) ) )
580- } else {
581- self . bytes_read = new_pos as _ ;
582-
583- Poll :: Ready ( Ok ( new_pos as _ ) )
584- }
610+ self . bytes_read = new_pos as _ ;
611+ Poll :: Ready ( Ok ( new_pos as _ ) )
585612 } else {
586613 Poll :: Ready ( Err ( std:: io:: Error :: new (
587614 std:: io:: ErrorKind :: InvalidInput ,
@@ -641,32 +668,21 @@ impl<'a> AsyncRead for SliceReader<'a> {
641668 }
642669}
643670
644- impl < ' a > AsyncSeek for SliceReader < ' a > {
645- fn poll_seek (
671+ impl < ' a > AsyncSeekForward for SliceReader < ' a > {
672+ fn poll_seek_forward (
646673 mut self : Pin < & mut Self > ,
647674 _cx : & mut Context < ' _ > ,
648- pos : SeekFrom ,
675+ offset : u64 ,
649676 ) -> Poll < std:: io:: Result < u64 > > {
650- let result = match pos {
651- SeekFrom :: Start ( offset) => offset. try_into ( ) ,
652- SeekFrom :: End ( offset) => self . bytes . len ( ) . try_into ( ) . map ( |len : i64 | len - offset) ,
653- SeekFrom :: Current ( offset) => self
654- . bytes_read
655- . try_into ( )
656- . map ( |bytes_read : i64 | bytes_read + offset) ,
657- } ;
677+ let result = self
678+ . bytes_read
679+ . try_into ( )
680+ . map ( |bytes_read : u64 | bytes_read + offset) ;
658681
659682 if let Ok ( new_pos) = result {
660- if new_pos < 0 {
661- Poll :: Ready ( Err ( std:: io:: Error :: new (
662- std:: io:: ErrorKind :: InvalidInput ,
663- "seek position is out of range" ,
664- ) ) )
665- } else {
666- self . bytes_read = new_pos as _ ;
683+ self . bytes_read = new_pos as _ ;
667684
668- Poll :: Ready ( Ok ( new_pos as _ ) )
669- }
685+ Poll :: Ready ( Ok ( new_pos as _ ) )
670686 } else {
671687 Poll :: Ready ( Err ( std:: io:: Error :: new (
672688 std:: io:: ErrorKind :: InvalidInput ,
0 commit comments