Another compile help

use std::io::{Read, Write, Error};
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};

trait XFlatFile: Sized {
    fn write(&self, writer: &mut dyn std::io::Write) -> Result<(), std::io::Error>;
    fn read(reader: &mut dyn std::io::Read) -> Result<Self, std::io::Error>;
}

impl XFlatFile for i32 {
    fn write(&self, writer: &mut dyn Write) -> Result<(), std::io::Error> {
        writer.write_i32::<LittleEndian>(*self)

    }

    fn read(reader: &mut dyn Read) -> Result<i32, std::io::Error> {
        reader.read_i32::<LittleEndian>()
    }
}

impl <A: XFlatFile, B: XFlatFile> XFlatFile for (A, B) {
    fn write(&self, writer: &mut dyn Write) -> Result<(), Error> {
        self.0.write(writer)?;
        self.1.write(writer)?;
        Ok(())
    }

    fn read(reader: &mut dyn Read) -> Result<Self, Error> {
        let a = reader.read::<A>()?;
        let b = reader.read::<B>()?;
        Ok((a, b))
    }
}

the part I am stuck on is the reader.read::<A>() part. So I need a way to somehow signal that we are reading an A first then a B afterwards.

Not sure why you didn't use the read method from the trait, like you did for write, but this compiles:

fn read(reader: &mut dyn Read) -> Result<Self, Error> {
    let a = A::read(reader)?;
    let b = B::read(reader)?;
    Ok((a, b))
}

Playground

1 Like
  1. Thanks, it worked.

  2. I wrote the wirte as

        self.0.write(writer)?;
        self.1.write(writer)?;

which threw me off. If, instead, I had written the equivalent of

        A::write(&self.0, writer)?;
        B::write(&self.0, writer)?;

then it would have been obvious

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.