embedded_io/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![warn(missing_docs)]
4#![doc = include_str!("../README.md")]
5
6use core::fmt;
7
8#[cfg(feature = "alloc")]
9extern crate alloc;
10
11mod impls;
12
13/// Enumeration of possible methods to seek within an I/O object.
14///
15/// This is the `embedded-io` equivalent of [`std::io::SeekFrom`].
16#[derive(Debug, Copy, Clone, Eq, PartialEq)]
17#[cfg_attr(feature = "defmt", derive(defmt::Format))]
18pub enum SeekFrom {
19 /// Sets the offset to the provided number of bytes.
20 Start(u64),
21 /// Sets the offset to the size of this object plus the specified number of bytes.
22 End(i64),
23 /// Sets the offset to the current position plus the specified number of bytes.
24 Current(i64),
25}
26
27#[cfg(feature = "std")]
28#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
29impl From<SeekFrom> for std::io::SeekFrom {
30 fn from(pos: SeekFrom) -> Self {
31 match pos {
32 SeekFrom::Start(n) => std::io::SeekFrom::Start(n),
33 SeekFrom::End(n) => std::io::SeekFrom::End(n),
34 SeekFrom::Current(n) => std::io::SeekFrom::Current(n),
35 }
36 }
37}
38
39#[cfg(feature = "std")]
40#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
41impl From<std::io::SeekFrom> for SeekFrom {
42 fn from(pos: std::io::SeekFrom) -> SeekFrom {
43 match pos {
44 std::io::SeekFrom::Start(n) => SeekFrom::Start(n),
45 std::io::SeekFrom::End(n) => SeekFrom::End(n),
46 std::io::SeekFrom::Current(n) => SeekFrom::Current(n),
47 }
48 }
49}
50
51/// Possible kinds of errors.
52///
53/// This list is intended to grow over time and it is not recommended to
54/// exhaustively match against it. In application code, use `match` for the `ErrorKind`
55/// values you are expecting; use `_` to match "all other errors".
56///
57/// This is the `embedded-io` equivalent of [`std::io::ErrorKind`], except with the following changes:
58///
59/// - `WouldBlock` is removed, since `embedded-io` traits are always blocking. See the [crate-level documentation](crate) for details.
60#[derive(Debug, Copy, Clone, Eq, PartialEq)]
61#[cfg_attr(feature = "defmt", derive(defmt::Format))]
62#[non_exhaustive]
63pub enum ErrorKind {
64 /// Unspecified error kind.
65 Other,
66
67 /// An entity was not found, often a file.
68 NotFound,
69 /// The operation lacked the necessary privileges to complete.
70 PermissionDenied,
71 /// The connection was refused by the remote server.
72 ConnectionRefused,
73 /// The connection was reset by the remote server.
74 ConnectionReset,
75 /// The connection was aborted (terminated) by the remote server.
76 ConnectionAborted,
77 /// The network operation failed because it was not connected yet.
78 NotConnected,
79 /// A socket address could not be bound because the address is already in
80 /// use elsewhere.
81 AddrInUse,
82 /// A nonexistent interface was requested or the requested address was not
83 /// local.
84 AddrNotAvailable,
85 /// The operation failed because a pipe was closed.
86 BrokenPipe,
87 /// An entity already exists, often a file.
88 AlreadyExists,
89 /// A parameter was incorrect.
90 InvalidInput,
91 /// Data not valid for the operation were encountered.
92 ///
93 /// Unlike [`InvalidInput`], this typically means that the operation
94 /// parameters were valid, however the error was caused by malformed
95 /// input data.
96 ///
97 /// For example, a function that reads a file into a string will error with
98 /// `InvalidData` if the file's contents are not valid UTF-8.
99 ///
100 /// [`InvalidInput`]: ErrorKind::InvalidInput
101 InvalidData,
102 /// The I/O operation's timeout expired, causing it to be canceled.
103 TimedOut,
104 /// This operation was interrupted.
105 ///
106 /// Interrupted operations can typically be retried.
107 Interrupted,
108 /// This operation is unsupported on this platform.
109 ///
110 /// This means that the operation can never succeed.
111 Unsupported,
112 /// An operation could not be completed, because it failed
113 /// to allocate enough memory.
114 OutOfMemory,
115 /// An attempted write could not write any data.
116 WriteZero,
117}
118
119#[cfg(feature = "std")]
120#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
121impl From<ErrorKind> for std::io::ErrorKind {
122 fn from(value: ErrorKind) -> Self {
123 match value {
124 ErrorKind::NotFound => std::io::ErrorKind::NotFound,
125 ErrorKind::PermissionDenied => std::io::ErrorKind::PermissionDenied,
126 ErrorKind::ConnectionRefused => std::io::ErrorKind::ConnectionRefused,
127 ErrorKind::ConnectionReset => std::io::ErrorKind::ConnectionReset,
128 ErrorKind::ConnectionAborted => std::io::ErrorKind::ConnectionAborted,
129 ErrorKind::NotConnected => std::io::ErrorKind::NotConnected,
130 ErrorKind::AddrInUse => std::io::ErrorKind::AddrInUse,
131 ErrorKind::AddrNotAvailable => std::io::ErrorKind::AddrNotAvailable,
132 ErrorKind::BrokenPipe => std::io::ErrorKind::BrokenPipe,
133 ErrorKind::AlreadyExists => std::io::ErrorKind::AlreadyExists,
134 ErrorKind::InvalidInput => std::io::ErrorKind::InvalidInput,
135 ErrorKind::InvalidData => std::io::ErrorKind::InvalidData,
136 ErrorKind::TimedOut => std::io::ErrorKind::TimedOut,
137 ErrorKind::Interrupted => std::io::ErrorKind::Interrupted,
138 ErrorKind::Unsupported => std::io::ErrorKind::Unsupported,
139 ErrorKind::OutOfMemory => std::io::ErrorKind::OutOfMemory,
140 ErrorKind::WriteZero => std::io::ErrorKind::WriteZero,
141 _ => std::io::ErrorKind::Other,
142 }
143 }
144}
145
146#[cfg(feature = "std")]
147#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
148impl From<std::io::ErrorKind> for ErrorKind {
149 fn from(value: std::io::ErrorKind) -> Self {
150 match value {
151 std::io::ErrorKind::NotFound => ErrorKind::NotFound,
152 std::io::ErrorKind::PermissionDenied => ErrorKind::PermissionDenied,
153 std::io::ErrorKind::ConnectionRefused => ErrorKind::ConnectionRefused,
154 std::io::ErrorKind::ConnectionReset => ErrorKind::ConnectionReset,
155 std::io::ErrorKind::ConnectionAborted => ErrorKind::ConnectionAborted,
156 std::io::ErrorKind::NotConnected => ErrorKind::NotConnected,
157 std::io::ErrorKind::AddrInUse => ErrorKind::AddrInUse,
158 std::io::ErrorKind::AddrNotAvailable => ErrorKind::AddrNotAvailable,
159 std::io::ErrorKind::BrokenPipe => ErrorKind::BrokenPipe,
160 std::io::ErrorKind::AlreadyExists => ErrorKind::AlreadyExists,
161 std::io::ErrorKind::InvalidInput => ErrorKind::InvalidInput,
162 std::io::ErrorKind::InvalidData => ErrorKind::InvalidData,
163 std::io::ErrorKind::TimedOut => ErrorKind::TimedOut,
164 std::io::ErrorKind::Interrupted => ErrorKind::Interrupted,
165 std::io::ErrorKind::Unsupported => ErrorKind::Unsupported,
166 std::io::ErrorKind::OutOfMemory => ErrorKind::OutOfMemory,
167 std::io::ErrorKind::WriteZero => ErrorKind::WriteZero,
168 _ => ErrorKind::Other,
169 }
170 }
171}
172
173/// Error trait.
174///
175/// This trait allows generic code to do limited inspecting of errors,
176/// to react differently to different kinds.
177pub trait Error: core::error::Error {
178 /// Get the kind of this error.
179 fn kind(&self) -> ErrorKind;
180}
181
182impl Error for core::convert::Infallible {
183 fn kind(&self) -> ErrorKind {
184 match *self {}
185 }
186}
187
188impl Error for ErrorKind {
189 fn kind(&self) -> ErrorKind {
190 *self
191 }
192}
193
194impl core::error::Error for ErrorKind {}
195
196impl fmt::Display for ErrorKind {
197 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198 write!(f, "{self:?}")
199 }
200}
201
202#[cfg(feature = "std")]
203#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
204impl Error for std::io::Error {
205 fn kind(&self) -> ErrorKind {
206 self.kind().into()
207 }
208}
209
210/// Base trait for all IO traits, defining the error type.
211///
212/// All IO operations of all traits return the error defined in this trait.
213///
214/// Having a shared trait instead of having every trait define its own
215/// `Error` associated type enforces all impls on the same type use the same error.
216/// This is very convenient when writing generic code, it means you have to
217/// handle a single error type `T::Error`, instead of `<T as Read>::Error` and `<T as Write>::Error`
218/// which might be different types.
219pub trait ErrorType {
220 /// Error type of all the IO operations on this type.
221 type Error: Error;
222}
223
224impl<T: ?Sized + ErrorType> ErrorType for &mut T {
225 type Error = T::Error;
226}
227
228/// Error returned by [`Read::read_exact`]
229#[derive(Debug, Copy, Clone, Eq, PartialEq)]
230#[cfg_attr(feature = "defmt", derive(defmt::Format))]
231pub enum ReadExactError<E> {
232 /// An EOF error was encountered before reading the exact amount of requested bytes.
233 UnexpectedEof,
234 /// Error returned by the inner Read.
235 Other(E),
236}
237
238impl<E> From<E> for ReadExactError<E> {
239 fn from(err: E) -> Self {
240 Self::Other(err)
241 }
242}
243
244#[cfg(feature = "std")]
245#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
246impl From<ReadExactError<std::io::Error>> for std::io::Error {
247 fn from(err: ReadExactError<std::io::Error>) -> Self {
248 match err {
249 ReadExactError::UnexpectedEof => std::io::Error::new(
250 std::io::ErrorKind::UnexpectedEof,
251 "UnexpectedEof".to_owned(),
252 ),
253 ReadExactError::Other(e) => std::io::Error::new(e.kind(), format!("{e:?}")),
254 }
255 }
256}
257
258impl<E: fmt::Debug> fmt::Display for ReadExactError<E> {
259 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
260 write!(f, "{self:?}")
261 }
262}
263
264impl<E: fmt::Debug> core::error::Error for ReadExactError<E> {}
265
266/// Errors that could be returned by `Write` on `&mut [u8]`.
267#[derive(Debug, Copy, Clone, Eq, PartialEq)]
268#[cfg_attr(feature = "defmt", derive(defmt::Format))]
269#[non_exhaustive]
270pub enum SliceWriteError {
271 /// The target slice was full and so could not receive any new data.
272 Full,
273}
274
275/// Error returned by [`Write::write_fmt`]
276#[derive(Debug, Copy, Clone, Eq, PartialEq)]
277#[cfg_attr(feature = "defmt", derive(defmt::Format))]
278pub enum WriteFmtError<E> {
279 /// An error was encountered while formatting.
280 FmtError,
281 /// Error returned by the inner Write.
282 Other(E),
283}
284
285impl<E> From<E> for WriteFmtError<E> {
286 fn from(err: E) -> Self {
287 Self::Other(err)
288 }
289}
290
291impl<E: fmt::Debug> fmt::Display for WriteFmtError<E> {
292 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
293 write!(f, "{self:?}")
294 }
295}
296
297impl<E: fmt::Debug> core::error::Error for WriteFmtError<E> {}
298
299/// Blocking reader.
300///
301/// This trait is the `embedded-io` equivalent of [`std::io::Read`].
302pub trait Read: ErrorType {
303 /// Read some bytes from this source into the specified buffer, returning how many bytes were read.
304 ///
305 /// If no bytes are currently available to read:
306 /// - The method blocks until at least one byte becomes available;
307 /// - Once at least one (or more) bytes become available, a non-zero amount of those is copied to the
308 /// beginning of `buf`, and the amount is returned, *without waiting or blocking any further for
309 /// more bytes to become available*.
310 ///
311 /// If bytes are available to read:
312 /// - A non-zero amount of bytes is read to the beginning of `buf`, and the amount is returned immediately,
313 /// *without blocking and waiting for more bytes to become available*;
314 ///
315 /// Note that once some bytes are available to read, it is *not* guaranteed that all available bytes are returned.
316 /// It is possible for the implementation to read an amount of bytes less than `buf.len()` while there are more
317 /// bytes immediately available.
318 ///
319 /// This blocking behavior is important for the cases where `Read` represents the "read" leg of a pipe-like
320 /// protocol (a socket, a pipe, a serial line etc.). The semantics is that the caller - by passing a non-empty
321 /// buffer - does expect _some_ data (one or more bytes) - but _not necessarily `buf.len()` or more bytes_ -
322 /// to become available, before the peer represented by `Read` would stop sending bytes due to
323 /// application-specific reasons (as in the peer waiting for a response to the data it had sent so far).
324 ///
325 /// If the reader is at end-of-file (EOF), `Ok(0)` is returned. There is no guarantee that a reader at EOF
326 /// will always be so in the future, for example a reader can stop being at EOF if another process appends
327 /// more bytes to the underlying file.
328 ///
329 /// If `buf.len() == 0`, `read` returns without blocking, with either `Ok(0)` or an error.
330 /// The `Ok(0)` doesn't indicate EOF, unlike when called with a non-empty buffer.
331 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
332
333 /// Read the exact number of bytes required to fill `buf`.
334 ///
335 /// This function calls `read()` in a loop until exactly `buf.len()` bytes have
336 /// been read, blocking if needed.
337 ///
338 /// If you are using [`ReadReady`] to avoid blocking, you should not use this function.
339 /// `ReadReady::read_ready()` returning true only guarantees the first call to `read()` will
340 /// not block, so this function may still block in subsequent calls.
341 fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<(), ReadExactError<Self::Error>> {
342 while !buf.is_empty() {
343 match self.read(buf) {
344 Ok(0) => break,
345 Ok(n) => buf = &mut buf[n..],
346 Err(e) => return Err(ReadExactError::Other(e)),
347 }
348 }
349 if buf.is_empty() {
350 Ok(())
351 } else {
352 Err(ReadExactError::UnexpectedEof)
353 }
354 }
355}
356
357/// Blocking buffered reader.
358///
359/// This trait is the `embedded-io` equivalent of [`std::io::BufRead`].
360pub trait BufRead: Read {
361 /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty.
362 ///
363 /// If no bytes are currently available to read, this function blocks until at least one byte is available.
364 ///
365 /// If the reader is at end-of-file (EOF), an empty slice is returned. There is no guarantee that a reader at EOF
366 /// will always be so in the future, for example a reader can stop being at EOF if another process appends
367 /// more bytes to the underlying file.
368 fn fill_buf(&mut self) -> Result<&[u8], Self::Error>;
369
370 /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`.
371 fn consume(&mut self, amt: usize);
372}
373
374/// Blocking writer.
375///
376/// This trait is the `embedded-io` equivalent of [`std::io::Write`].
377pub trait Write: ErrorType {
378 /// Write a buffer into this writer, returning how many bytes were written.
379 ///
380 /// If the writer is not currently ready to accept more bytes (for example, its buffer is full),
381 /// this function blocks until it is ready to accept least one byte.
382 ///
383 /// If it's ready to accept bytes, a non-zero amount of bytes is written from the beginning of `buf`, and the amount
384 /// is returned. It is not guaranteed that *all* available buffer space is filled, i.e. it is possible for the
385 /// implementation to write an amount of bytes less than `buf.len()` while the writer continues to be
386 /// ready to accept more bytes immediately.
387 ///
388 /// Implementations must not return `Ok(0)` unless `buf` is empty. Situations where the
389 /// writer is not able to accept more bytes must instead be indicated with an error,
390 /// where the `ErrorKind` is `WriteZero`.
391 ///
392 /// If `buf` is empty, `write` returns without blocking, with either `Ok(0)` or an error.
393 /// `Ok(0)` doesn't indicate an error.
394 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error>;
395
396 /// Flush this output stream, blocking until all intermediately buffered contents reach their destination.
397 fn flush(&mut self) -> Result<(), Self::Error>;
398
399 /// Write an entire buffer into this writer.
400 ///
401 /// This function calls `write()` in a loop until exactly `buf.len()` bytes have
402 /// been written, blocking if needed.
403 ///
404 /// If you are using [`WriteReady`] to avoid blocking, you should not use this function.
405 /// `WriteReady::write_ready()` returning true only guarantees the first call to `write()` will
406 /// not block, so this function may still block in subsequent calls.
407 ///
408 /// This function will panic if `write()` returns `Ok(0)`.
409 fn write_all(&mut self, mut buf: &[u8]) -> Result<(), Self::Error> {
410 while !buf.is_empty() {
411 match self.write(buf) {
412 Ok(0) => panic!("write() returned Ok(0)"),
413 Ok(n) => buf = &buf[n..],
414 Err(e) => return Err(e),
415 }
416 }
417 Ok(())
418 }
419
420 /// Write a formatted string into this writer, returning any error encountered.
421 ///
422 /// This function calls `write()` in a loop until the entire formatted string has
423 /// been written, blocking if needed.
424 ///
425 /// If you are using [`WriteReady`] to avoid blocking, you should not use this function.
426 /// `WriteReady::write_ready()` returning true only guarantees the first call to `write()` will
427 /// not block, so this function may still block in subsequent calls.
428 ///
429 /// Unlike [`Write::write`], the number of bytes written is not returned. However, in the case of
430 /// writing to an `&mut [u8]` its possible to calculate the number of bytes written by subtracting
431 /// the length of the slice after the write, from the initial length of the slice.
432 ///
433 /// ```rust
434 /// # use embedded_io::Write;
435 /// let mut buf: &mut [u8] = &mut [0u8; 256];
436 /// let start = buf.len();
437 /// let len = write!(buf, "{}", "Test").and_then(|_| Ok(start - buf.len()));
438 /// ```
439 fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<(), WriteFmtError<Self::Error>> {
440 // Create a shim which translates a Write to a fmt::Write and saves
441 // off I/O errors. instead of discarding them
442 struct Adapter<'a, T: Write + ?Sized + 'a> {
443 inner: &'a mut T,
444 error: Result<(), T::Error>,
445 }
446
447 impl<T: Write + ?Sized> fmt::Write for Adapter<'_, T> {
448 fn write_str(&mut self, s: &str) -> fmt::Result {
449 match self.inner.write_all(s.as_bytes()) {
450 Ok(()) => Ok(()),
451 Err(e) => {
452 self.error = Err(e);
453 Err(fmt::Error)
454 }
455 }
456 }
457 }
458
459 let mut output = Adapter {
460 inner: self,
461 error: Ok(()),
462 };
463 match fmt::write(&mut output, fmt) {
464 Ok(()) => Ok(()),
465 Err(..) => match output.error {
466 // check if the error came from the underlying `Write` or not
467 Err(e) => Err(WriteFmtError::Other(e)),
468 Ok(()) => Err(WriteFmtError::FmtError),
469 },
470 }
471 }
472}
473
474/// Blocking seek within streams.\
475///
476/// The `Seek` trait provides a cursor which can be moved within a stream of
477/// bytes.
478///
479/// The stream typically has a fixed size, allowing seeking relative to either
480/// end or the current offset.
481///
482/// This trait is the `embedded-io` equivalent of [`std::io::Seek`].
483pub trait Seek: ErrorType {
484 /// Seek to an offset, in bytes, in a stream.
485 /// A seek beyond the end of a stream is allowed, but behavior is defined
486 /// by the implementation.
487 ///
488 /// If the seek operation completed successfully,
489 /// this method returns the new position from the start of the stream.
490 /// That position can be used later with [`SeekFrom::Start`].
491 ///
492 /// # Errors
493 ///
494 /// Seeking can fail, for example because it might involve flushing a buffer.
495 ///
496 /// Seeking to a negative offset is considered an error.
497 fn seek(&mut self, pos: SeekFrom) -> Result<u64, Self::Error>;
498
499 /// Rewind to the beginning of a stream.
500 ///
501 /// This is a convenience method, equivalent to `seek(SeekFrom::Start(0))`.
502 ///
503 /// # Errors
504 ///
505 /// Rewinding can fail, for example because it might involve flushing a buffer.
506 fn rewind(&mut self) -> Result<(), Self::Error> {
507 self.seek(SeekFrom::Start(0))?;
508 Ok(())
509 }
510
511 /// Returns the current seek position from the start of the stream.
512 ///
513 /// This is equivalent to `self.seek(SeekFrom::Current(0))`.
514 fn stream_position(&mut self) -> Result<u64, Self::Error> {
515 self.seek(SeekFrom::Current(0))
516 }
517
518 /// Seeks relative to the current position.
519 ///
520 /// This is equivalent to `self.seek(SeekFrom::Current(offset))` but
521 /// doesn't return the new position which can allow some implementations
522 /// to perform more efficient seeks.
523 fn seek_relative(&mut self, offset: i64) -> Result<(), Self::Error> {
524 self.seek(SeekFrom::Current(offset))?;
525 Ok(())
526 }
527}
528
529/// Get whether a reader is ready.
530///
531/// This allows using a [`Read`] or [`BufRead`] in a nonblocking fashion, i.e. trying to read
532/// only when it is ready.
533pub trait ReadReady: Read {
534 /// Get whether the reader is ready for immediately reading.
535 ///
536 /// This usually means that there is either some bytes have been received and are buffered and ready to be read,
537 /// or that the reader is at EOF.
538 ///
539 /// If this returns `true`, it's guaranteed that the next call to [`Read::read`] or [`BufRead::fill_buf`] will not block.
540 fn read_ready(&mut self) -> Result<bool, Self::Error>;
541}
542
543/// Get whether a writer is ready.
544///
545/// This allows using a [`Write`] in a nonblocking fashion, i.e. trying to write
546/// only when it is ready.
547pub trait WriteReady: Write {
548 /// Get whether the writer is ready for immediately writing.
549 ///
550 /// This usually means that there is free space in the internal transmit buffer.
551 ///
552 /// If this returns `true`, it's guaranteed that the next call to [`Write::write`] will not block.
553 fn write_ready(&mut self) -> Result<bool, Self::Error>;
554}
555
556impl<T: ?Sized + Read> Read for &mut T {
557 #[inline]
558 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
559 T::read(self, buf)
560 }
561
562 #[inline]
563 fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError<Self::Error>> {
564 T::read_exact(self, buf)
565 }
566}
567
568impl<T: ?Sized + BufRead> BufRead for &mut T {
569 #[inline]
570 fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
571 T::fill_buf(self)
572 }
573
574 #[inline]
575 fn consume(&mut self, amt: usize) {
576 T::consume(self, amt);
577 }
578}
579
580impl<T: ?Sized + Write> Write for &mut T {
581 #[inline]
582 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
583 T::write(self, buf)
584 }
585
586 #[inline]
587 fn flush(&mut self) -> Result<(), Self::Error> {
588 T::flush(self)
589 }
590
591 #[inline]
592 fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
593 T::write_all(self, buf)
594 }
595}
596
597impl<T: ?Sized + Seek> Seek for &mut T {
598 #[inline]
599 fn seek(&mut self, pos: SeekFrom) -> Result<u64, Self::Error> {
600 T::seek(self, pos)
601 }
602
603 #[inline]
604 fn rewind(&mut self) -> Result<(), Self::Error> {
605 T::rewind(self)
606 }
607
608 #[inline]
609 fn stream_position(&mut self) -> Result<u64, Self::Error> {
610 T::stream_position(self)
611 }
612
613 #[inline]
614 fn seek_relative(&mut self, offset: i64) -> Result<(), Self::Error> {
615 T::seek_relative(self, offset)
616 }
617}
618
619impl<T: ?Sized + ReadReady> ReadReady for &mut T {
620 #[inline]
621 fn read_ready(&mut self) -> Result<bool, Self::Error> {
622 T::read_ready(self)
623 }
624}
625
626impl<T: ?Sized + WriteReady> WriteReady for &mut T {
627 #[inline]
628 fn write_ready(&mut self) -> Result<bool, Self::Error> {
629 T::write_ready(self)
630 }
631}