Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there a way to prevent try_from from consuming a mutable reference?

I have a struct

struct Triangle {
    normal: Normal,
    vertices: [Vertex; 3],
}

that I’d like to deserialize from a Read type. I thought implementing TryFrom would be idiomatic since I’m turning a stream of bytes into a Triangle but it may fail.

impl TryFrom<&mut dyn std::io::Read> for Triangle {
  type Error = std::io::Error;
  fn try_from(reader: &mut dyn std::io::Read) -> Result<Self, Self::Error> {
    Ok(Self {
        normal: Normal::try_from(reader)?,
        vertices: [Vertex::try_from(reader)?, Vertex::try_from(reader)?, Vertex::try_from(reader)?]
    })
  }
}

I believe I could shove all of the usage of the reader : &mut Read into the Triangle implementation but

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  1. I like having the parsing for an object in its own impl and
  2. I’ll just run into the same problem when I try to parse multiple Triangles to build a mesh

I’m starting to get the feeling that implementing TryFrom is the wrong approach here but before I gave up I thought I’d ask if there was a clean way to let Normal::try_From borrow the reader then let Vertex::try_from borrow the reader while following ownership rules.

Here is a full listing of the module: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d79881fee912acf0fa4496f90a34df86

(I know that STL has a u16 attribute after each triangle, just haven’t gotten around to it yet)

>Solution :

You can fully qualify the call, although it is not obvious to me why it doesn’t compile in the first place:

impl TryFrom<&mut dyn std::io::Read> for Triangle {
    type Error = std::io::Error;
    fn try_from(reader: &mut dyn std::io::Read) -> Result<Self, Self::Error> {
        Ok(Self {
            normal: <Normal as TryFrom<&mut dyn std::io::Read>>::try_from(reader)?,
            vertices: [
                <Vertex as TryFrom<&mut dyn std::io::Read>>::try_from(reader)?,
                <Vertex as TryFrom<&mut dyn std::io::Read>>::try_from(reader)?,
                Vertex::try_from(reader)?,
            ],
        })
    }
}

But I’d just implement a custom method.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading