From 83299d17f666f40d252731893fa97adba8c22b4f Mon Sep 17 00:00:00 2001 From: Lukasz Anforowicz Date: Fri, 22 Nov 2024 15:26:12 +0000 Subject: [PATCH] `impl Write for UniquePtr where ... Pin<&a mut T> : Write`. This commit implements forwarding of `Write` trait implementation from `UniquePtr` to the pointee type. This is quite similar to how `Box` also forwards - see https://doc.rust-lang.org/std/boxed/struct.Box.html#impl-Write-for-Box%3CW%3E This commit has quite similar, orphan-rule-related motivation as the earlier https://github.com/dtolnay/cxx/pull/1368 which covered the `Read` trait. For a more specific motivating example, please see http://review.skia.org/c/skia/+/923337/3/experimental/rust_png/ffi/FFI.rs#254 --- src/unique_ptr.rs | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/unique_ptr.rs b/src/unique_ptr.rs index b56dbe885..ac3872942 100644 --- a/src/unique_ptr.rs +++ b/src/unique_ptr.rs @@ -14,7 +14,7 @@ use core::mem::{self, MaybeUninit}; use core::ops::{Deref, DerefMut}; use core::pin::Pin; #[cfg(feature = "std")] -use std::io::{self, Read}; +use std::io::{self, Read, Write}; /// Binding to C++ `std::unique_ptr>`. #[repr(C)] @@ -220,6 +220,44 @@ where // `read_buf` and/or `is_read_vectored`). } +/// Forwarding `Write` trait implementation in a manner similar to `Box`. +/// +/// Note that the implementation will panic for null `UniquePtr`. +#[cfg(feature = "std")] +impl Write for UniquePtr +where + for<'a> Pin<&'a mut T>: Write, + T: UniquePtrTarget, +{ + #[inline] + fn write(&mut self, buf: &[u8]) -> io::Result { + self.pin_mut().write(buf) + } + + #[inline] + fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { + self.pin_mut().write_vectored(bufs) + } + + #[inline] + fn flush(&mut self) -> io::Result<()> { + self.pin_mut().flush() + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.pin_mut().write_all(buf) + } + + #[inline] + fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { + self.pin_mut().write_fmt(fmt) + } + + // TODO: Foward other `Write` trait methods when they get stabilized (e.g. + // `write_all_vectored` and/or `is_write_vectored`). +} + /// Trait bound for types which may be used as the `T` inside of a /// `UniquePtr` in generic code. ///