The right or best way of convert two approximative struct?

Sometimes, there are several very close structures in my program.

struct A {
   a:i32,
   b:String
}

struct B {
   id:i32,
   a:i32,
   b:String
}

What the best way to convert B to A?

Is there a way to do it like this?

let b = B{.....};
let a:A = Omit(b,'id')

Rust does not have any convenience syntax for this. You need to do this:

A {
    a: b.a,
    b: b.b,
}
1 Like

You might use patterns and shorthands for this:

pub fn convert(the_b: B) -> A {
    let B { a, b, .. } = the_b;
    A { a, b }
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7457ad99ed2b8b8e5b6365ee2a4f5c47

yes, this is useful. let's see an other example.


// this struct for http post user info.
struct RequestUserPayload{
first_name:String,
last_name:String,
age:u8,
email:String,
// and more details
}


// this struct for database table mapping
struct User{
id:u32,
first_name:String,
last_name:String,
age:u8,
email:String,
// same as RequestUserPayload field
create_at: NaiveDateTime,
update_at: NaiveDateTime
}

The User struct include RequestUserPayload. So, I think there is an easy way to convert it.
Maybe, it could use memory copy or pointer? I dont know.

Honestly, the solutions from @alice and @scottmcm are the best, both in terms of readability and performance.

To put this in perspective, I've copied your structs and @scottmcm's solution to the playground.

fn convert(the_b: B) -> A {
    let B { a, b, .. } = the_b;
    A { a, b }
}

The entire convert() function compiles down to half a dozen move statements when building in release mode.

playground::convert:
	movl	28(%rsi), %eax
	movq	16(%rsi), %rcx
	movq	%rcx, 16(%rdi)
	movups	(%rsi), %xmm0
	movups	%xmm0, (%rdi)
	movl	%eax, 24(%rdi)
	retq

You could try to do something fancy with procedural macros or unsafe, but that'll just make it hard to understand what is going on and probably be slower at runtime. The optimiser will need to peel away any layers of abstraction you add, and unsafe code can sometimes hurt performance because the optimiser can't make assumptions that might minimise work.

1 Like