Skip to content

Commit e2cb281

Browse files
authored
Rollup merge of rust-lang#92663 - cuviper:generic-write-cursor, r=dtolnay
Implement `Write for Cursor<[u8; N]>`, plus `A: Allocator` cursor support This implements `Write for Cursor<[u8; N]>`, and also adds support for generic `A: Allocator` in `Box` and `Vec` cursors. This was inspired by a user questioning why they couldn't write a `Cursor<[u8; N]>`: https://users.rust-lang.org/t/why-vec-and-not-u8-makes-cursor-have-write/68210 Related history: - rust-lang#27197 switched `AsRef<[u8]>` for reading and seeking - rust-lang#67415 tried to use `AsMut<[u8]>` for writing, but did not specialize `Vec`.
2 parents 59e51a8 + 7d44316 commit e2cb281

File tree

2 files changed

+86
-51
lines changed

2 files changed

+86
-51
lines changed

library/std/src/io/cursor.rs

+46-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod tests;
33

44
use crate::io::prelude::*;
55

6+
use crate::alloc::Allocator;
67
use crate::cmp;
78
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
89

@@ -398,7 +399,10 @@ fn slice_write_vectored(
398399
}
399400

400401
// Resizing write implementation
401-
fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
402+
fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
403+
where
404+
A: Allocator,
405+
{
402406
let pos: usize = (*pos_mut).try_into().map_err(|_| {
403407
io::const_io_error!(
404408
ErrorKind::InvalidInput,
@@ -426,11 +430,14 @@ fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usi
426430
Ok(buf.len())
427431
}
428432

429-
fn vec_write_vectored(
433+
fn vec_write_vectored<A>(
430434
pos_mut: &mut u64,
431-
vec: &mut Vec<u8>,
435+
vec: &mut Vec<u8, A>,
432436
bufs: &[IoSlice<'_>],
433-
) -> io::Result<usize> {
437+
) -> io::Result<usize>
438+
where
439+
A: Allocator,
440+
{
434441
let mut nwritten = 0;
435442
for buf in bufs {
436443
nwritten += vec_write(pos_mut, vec, buf)?;
@@ -462,7 +469,10 @@ impl Write for Cursor<&mut [u8]> {
462469
}
463470

464471
#[stable(feature = "cursor_mut_vec", since = "1.25.0")]
465-
impl Write for Cursor<&mut Vec<u8>> {
472+
impl<A> Write for Cursor<&mut Vec<u8, A>>
473+
where
474+
A: Allocator,
475+
{
466476
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
467477
vec_write(&mut self.pos, self.inner, buf)
468478
}
@@ -483,7 +493,10 @@ impl Write for Cursor<&mut Vec<u8>> {
483493
}
484494

485495
#[stable(feature = "rust1", since = "1.0.0")]
486-
impl Write for Cursor<Vec<u8>> {
496+
impl<A> Write for Cursor<Vec<u8, A>>
497+
where
498+
A: Allocator,
499+
{
487500
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
488501
vec_write(&mut self.pos, &mut self.inner, buf)
489502
}
@@ -504,7 +517,33 @@ impl Write for Cursor<Vec<u8>> {
504517
}
505518

506519
#[stable(feature = "cursor_box_slice", since = "1.5.0")]
507-
impl Write for Cursor<Box<[u8]>> {
520+
impl<A> Write for Cursor<Box<[u8], A>>
521+
where
522+
A: Allocator,
523+
{
524+
#[inline]
525+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
526+
slice_write(&mut self.pos, &mut self.inner, buf)
527+
}
528+
529+
#[inline]
530+
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
531+
slice_write_vectored(&mut self.pos, &mut self.inner, bufs)
532+
}
533+
534+
#[inline]
535+
fn is_write_vectored(&self) -> bool {
536+
true
537+
}
538+
539+
#[inline]
540+
fn flush(&mut self) -> io::Result<()> {
541+
Ok(())
542+
}
543+
}
544+
545+
#[stable(feature = "cursor_array", since = "1.61.0")]
546+
impl<const N: usize> Write for Cursor<[u8; N]> {
508547
#[inline]
509548
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
510549
slice_write(&mut self.pos, &mut self.inner, buf)

library/std/src/io/cursor/tests.rs

+40-44
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,11 @@ fn test_mem_mut_writer() {
5050
assert_eq!(&writer.get_ref()[..], b);
5151
}
5252

53-
#[test]
54-
fn test_box_slice_writer() {
55-
let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
53+
fn test_slice_writer<T>(writer: &mut Cursor<T>)
54+
where
55+
T: AsRef<[u8]>,
56+
Cursor<T>: Write,
57+
{
5658
assert_eq!(writer.position(), 0);
5759
assert_eq!(writer.write(&[0]).unwrap(), 1);
5860
assert_eq!(writer.position(), 1);
@@ -65,12 +67,14 @@ fn test_box_slice_writer() {
6567
assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
6668
assert_eq!(writer.write(&[10]).unwrap(), 0);
6769
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
68-
assert_eq!(&**writer.get_ref(), b);
70+
assert_eq!(writer.get_ref().as_ref(), b);
6971
}
7072

71-
#[test]
72-
fn test_box_slice_writer_vectored() {
73-
let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
73+
fn test_slice_writer_vectored<T>(writer: &mut Cursor<T>)
74+
where
75+
T: AsRef<[u8]>,
76+
Cursor<T>: Write,
77+
{
7478
assert_eq!(writer.position(), 0);
7579
assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1);
7680
assert_eq!(writer.position(), 1);
@@ -85,53 +89,45 @@ fn test_box_slice_writer_vectored() {
8589
assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1);
8690
assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0);
8791
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
88-
assert_eq!(&**writer.get_ref(), b);
92+
assert_eq!(writer.get_ref().as_ref(), b);
93+
}
94+
95+
#[test]
96+
fn test_box_slice_writer() {
97+
let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
98+
test_slice_writer(&mut writer);
99+
}
100+
101+
#[test]
102+
fn test_box_slice_writer_vectored() {
103+
let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
104+
test_slice_writer_vectored(&mut writer);
105+
}
106+
107+
#[test]
108+
fn test_array_writer() {
109+
let mut writer = Cursor::new([0u8; 9]);
110+
test_slice_writer(&mut writer);
111+
}
112+
113+
#[test]
114+
fn test_array_writer_vectored() {
115+
let mut writer = Cursor::new([0u8; 9]);
116+
test_slice_writer_vectored(&mut writer);
89117
}
90118

91119
#[test]
92120
fn test_buf_writer() {
93121
let mut buf = [0 as u8; 9];
94-
{
95-
let mut writer = Cursor::new(&mut buf[..]);
96-
assert_eq!(writer.position(), 0);
97-
assert_eq!(writer.write(&[0]).unwrap(), 1);
98-
assert_eq!(writer.position(), 1);
99-
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
100-
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
101-
assert_eq!(writer.position(), 8);
102-
assert_eq!(writer.write(&[]).unwrap(), 0);
103-
assert_eq!(writer.position(), 8);
104-
105-
assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
106-
assert_eq!(writer.write(&[10]).unwrap(), 0);
107-
}
108-
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
109-
assert_eq!(buf, b);
122+
let mut writer = Cursor::new(&mut buf[..]);
123+
test_slice_writer(&mut writer);
110124
}
111125

112126
#[test]
113127
fn test_buf_writer_vectored() {
114128
let mut buf = [0 as u8; 9];
115-
{
116-
let mut writer = Cursor::new(&mut buf[..]);
117-
assert_eq!(writer.position(), 0);
118-
assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1);
119-
assert_eq!(writer.position(), 1);
120-
assert_eq!(
121-
writer
122-
.write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7])],)
123-
.unwrap(),
124-
7,
125-
);
126-
assert_eq!(writer.position(), 8);
127-
assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
128-
assert_eq!(writer.position(), 8);
129-
130-
assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1);
131-
assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0);
132-
}
133-
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
134-
assert_eq!(buf, b);
129+
let mut writer = Cursor::new(&mut buf[..]);
130+
test_slice_writer_vectored(&mut writer);
135131
}
136132

137133
#[test]

0 commit comments

Comments
 (0)