Idiomatic Vec<u8> -> Write

let t: Vec<u8> = ... ;
let mut c = std::io::Cursor::new(t);
func_requiring_write(&mut c);

Is std::io::Cursor a hack or an idiomatic approach ? (Used this a few times via google, but never formally read about, not sure if this is the 'correct' approach or not.)

Ehm… we do have

impl<A: Allocator> Write for Vec<u8, A>

too!?


Edit: Ah, or maybe you want to overwrite contents… in that case working with

impl Write for &mut [u8]

is another option.


Edit2: Looks like if you want behavior that does both start at the beginning, overwriting existing contents and has the ability to extend the capacity of the Vec, then Cursor is the only good option. Besides clearing the Vec, then writing to it, of course.

1 Like

Vec is Write by itself. Primary reason for io::Cursor is to support Seek over in-memory buffers.

1 Like

Sorry, this is an instance of the XY problem.

The following code does NOT compile:

        let mut out = Vec::<u8>::new();
        // let mut t = std::io::Cursor::new(&mut out);
        let mut encoder = image::codecs::bmp::BmpEncoder::new(&mut out);
        let img = RgbImage::new(self.width as u32, self.height as u32);
        img.write_to(&mut encoder).expect(format!(
            "PixelUI calc_base64 failed\n  width = {:?}\n  neight = {:?}\n",
            self.width, self.height,
        ));

It generates error:

error[E0277]: the trait bound `BmpEncoder<'_, std::vec::Vec<u8>>: std::io::Write` is not satisfied

     |
48   |         img.write_to(&mut encoder).expect(format!(
     |             -------- ^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `BmpEncoder<'_, std::vec::Vec<u8>>`
     |             |
     |             required by a bound introduced by this call
     |
note: required by a bound in `ImageBuffer::<P, Container>::write_to`

     |
1048 |     pub fn write_to<W, F>(&self, writer: &mut W, format: F) -> ImageResult<()>
     |            -------- required by a bound in this associated function
1049 |     where
1050 |         W: std::io::Write + std::io::Seek,
     |            ^^^^^^^^^^^^^^ required by this bound in `ImageBuffer::<P, Container>::write_to`

I incorrectly thought that Vec<u8> does not impl Write.

WTF am I doing wrong here ?

And introducing the Cursor makes a difference? The compiler error points out the requirement of needing Write implemented for BmpEncoder<…, something>, which I assume is this type, right? I can’t see any Write impl on that though.

2 Likes

I think you want

img.write_with_encoder(encoder).expect(...)

(Consider what traits BmpEncoder implements. Write is not one.)

2 Likes

No, adding cursor did not fix it. This is merely what initially caused me to think Vec did not impl. Write.

encoder.rs - source shows it impls Write right? Or am I mis reading it ? I'm clearly doing something wrong; I'm just not sure what.

That's a trait bound on a generic type parameter gating the definition of some inherent methods. It's not impl<...> Write for BmpEncoder<...>. It's utilizing W's implementation is all.

2 Likes
  1. Everything worked now, thanks.

  2. For the record, I'm generally not this incompetent at reading type signatures. :slight_smile:

2 Likes