Avba
Avba

Reputation: 15266

How to "cast" rust struct to another identical type (same fields/layout) without copying all members

I have a private type in one module which has identical fields to another type. I can't import one another (somehow share the types) since it will lead to a circular dependency and it will be very complicated to refactor to allow that.

Just for clarity, the struct looks like this in both modules:

struct Args {
   pub a: String,
   pub b: String,
   pub c: Option<PathBuf>,
}

In some situations I can "consume" one of the items so I will do std::mem::swap between the fields.

But in a case where consuming is not possible, and I need to send a reference of the other type it is cumbersome to create intermediate objects and swap back and forth for the sake of calling the function

for example in a case like this:

pub struct Args {
     pub a: String,
     pub b: String,
     pub c: Option<PathBuf>
}
fn main() {
  let args = crate::Args::default(); // this module Args
  crate::work(&args); // works obviously

  mod2::mod2_work(&args); // doesn't work

  // how to avoid this?
  let m2_args = mod2::work::Args { ... } // copy/clone from this args;

  mod2::mod2_work(&m2_args); // works

}

fn work(args: &Args) { } // this module args


// module 2 (different but same "Args")
// for the sake of this example assume even the same file
pub mod mod2 {
  pub struct Args {
     pub a: String,
     pub b: String,
     pub c: Option<PathBuf>
  }

  pub fn mod2_work(args: &mod2::Args) { } // module 2 args
}



Upvotes: 0

Views: 2214

Answers (1)

battlmonstr
battlmonstr

Reputation: 6280

If Args and mod2::Args are the same (same field names, same types), defining the second Args adds no value.

Instead you can alias it:

type MyArgs = mod2::Args;

or just bring into the scope:

use mod2::Args as MyArgs;

and then just treat it as your own type.

Having said that there's mem::transmute - black magic that does what you ask.

Upvotes: 2

Related Questions