@@ -22,15 +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 ,
2929 mem:: size_of,
3030 path:: { Path , PathBuf } ,
3131 pin:: Pin ,
3232 sync:: Arc ,
33- task:: { Context , Poll } ,
33+ task:: Poll ,
3434} ;
3535use thiserror:: Error ;
3636
@@ -81,13 +81,51 @@ pub const STACK_FUTURE_SIZE: usize = 10 * size_of::<&()>();
8181
8282pub use stackfuture:: StackFuture ;
8383
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+
84122/// A type returned from [`AssetReader::read`], which is used to read the contents of a file
85123/// (or virtual file) corresponding to an asset.
86124///
87- /// 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 `].
88126/// The only reason a blanket implementation is not provided for applicable types is to allow
89127/// implementors to override the provided implementation of [`Reader::read_to_end`].
90- pub trait Reader : AsyncRead + AsyncSeek + Unpin + Send + Sync {
128+ pub trait Reader : AsyncRead + AsyncSeekForward + Unpin + Send + Sync {
91129 /// Reads the entire contents of this reader and appends them to a vec.
92130 ///
93131 /// # Note for implementors
@@ -533,32 +571,20 @@ impl AsyncRead for VecReader {
533571 }
534572}
535573
536- impl AsyncSeek for VecReader {
537- fn poll_seek (
574+ impl AsyncSeekForward for VecReader {
575+ fn poll_seek_forward (
538576 mut self : Pin < & mut Self > ,
539577 _cx : & mut Context < ' _ > ,
540- pos : SeekFrom ,
578+ offset : u64 ,
541579 ) -> Poll < std:: io:: Result < u64 > > {
542- let result = match pos {
543- SeekFrom :: Start ( offset) => offset. try_into ( ) ,
544- SeekFrom :: End ( offset) => self . bytes . len ( ) . try_into ( ) . map ( |len : i64 | len - offset) ,
545- SeekFrom :: Current ( offset) => self
546- . bytes_read
547- . try_into ( )
548- . map ( |bytes_read : i64 | bytes_read + offset) ,
549- } ;
580+ let result = self
581+ . bytes_read
582+ . try_into ( )
583+ . map ( |bytes_read : u64 | bytes_read + offset) ;
550584
551585 if let Ok ( new_pos) = result {
552- if new_pos < 0 {
553- Poll :: Ready ( Err ( std:: io:: Error :: new (
554- std:: io:: ErrorKind :: InvalidInput ,
555- "seek position is out of range" ,
556- ) ) )
557- } else {
558- self . bytes_read = new_pos as _ ;
559-
560- Poll :: Ready ( Ok ( new_pos as _ ) )
561- }
586+ self . bytes_read = new_pos as _ ;
587+ Poll :: Ready ( Ok ( new_pos as _ ) )
562588 } else {
563589 Poll :: Ready ( Err ( std:: io:: Error :: new (
564590 std:: io:: ErrorKind :: InvalidInput ,
@@ -618,32 +644,21 @@ impl<'a> AsyncRead for SliceReader<'a> {
618644 }
619645}
620646
621- impl < ' a > AsyncSeek for SliceReader < ' a > {
622- fn poll_seek (
647+ impl < ' a > AsyncSeekForward for SliceReader < ' a > {
648+ fn poll_seek_forward (
623649 mut self : Pin < & mut Self > ,
624650 _cx : & mut Context < ' _ > ,
625- pos : SeekFrom ,
651+ offset : u64 ,
626652 ) -> Poll < std:: io:: Result < u64 > > {
627- let result = match pos {
628- SeekFrom :: Start ( offset) => offset. try_into ( ) ,
629- SeekFrom :: End ( offset) => self . bytes . len ( ) . try_into ( ) . map ( |len : i64 | len - offset) ,
630- SeekFrom :: Current ( offset) => self
631- . bytes_read
632- . try_into ( )
633- . map ( |bytes_read : i64 | bytes_read + offset) ,
634- } ;
653+ let result = self
654+ . bytes_read
655+ . try_into ( )
656+ . map ( |bytes_read : u64 | bytes_read + offset) ;
635657
636658 if let Ok ( new_pos) = result {
637- if new_pos < 0 {
638- Poll :: Ready ( Err ( std:: io:: Error :: new (
639- std:: io:: ErrorKind :: InvalidInput ,
640- "seek position is out of range" ,
641- ) ) )
642- } else {
643- self . bytes_read = new_pos as _ ;
659+ self . bytes_read = new_pos as _ ;
644660
645- Poll :: Ready ( Ok ( new_pos as _ ) )
646- }
661+ Poll :: Ready ( Ok ( new_pos as _ ) )
647662 } else {
648663 Poll :: Ready ( Err ( std:: io:: Error :: new (
649664 std:: io:: ErrorKind :: InvalidInput ,
0 commit comments