8

In others languages (like Java), libraries are available for mapping object fields to another object (like mapstruct). It is useful indeed for isolating controller and service from each other.

PersonDto personDto = mapper.businessToDto(personBusiness); 

And I can't find how to do it with Rust ? I didn't find any libraries helping with this, or any way to do it. Any resource would be very appreciated !

5
  • 1
    Rust isn't really OOP (at least not in the very pedantic Java sense), so this might not even make sense. In particular, the fact that we have traits seem to make something like mapstruct unnecessary. Commented Jun 25, 2020 at 12:52
  • Yeah, Mapstruct is just helpful to avoid fastidious hand mapping. How would traits make the struct mappings less tedious? Commented Jun 25, 2020 at 13:47
  • From the question, I expect the mapping function to be written manually, however in your comment you mention to avoid fastidious hand mapping: are looking for a manual or automatic mapping function? Commented Jun 25, 2020 at 13:51
  • It is true that I asked something out of the scope of the initial question. I was asking this for some more intel. Commented Jun 25, 2020 at 13:52
  • If you don't want to write the actual mapping by hand, instead relying on some annotation and/or conventions, you'd use a proc-macro. There isn't one proc-macro library to rule them all, but there are some pretty common ones. However I don't think this use-case is very common in Rust. Commented Jun 25, 2020 at 13:57

2 Answers 2

23

In rust you usually do it via From trait:

struct Person { name: String, age: u8, } struct PersonDto { name: String, age: u64, } impl From<Person> for PersonDto { fn from(p: Person) -> Self { Self { name: p.name, age: p.age.into(), } } } 

So you can make an Into conversion:

let person = Person { name: "Alex".to_string(), age: 42 }; let person_dto: PersonDto = person.into(); // or via an explicit `T::from: let person_dto = PersonDto::from(person); 
Sign up to request clarification or add additional context in comments.

1 Comment

this would make the code longer, is it possible to BeanCopy/MapStruct like java
3

In a comment, author of the question mentioned 'avoiding fastidious hand mapping' as part of their question. Rust crate o2o (which I am the author of) tries to deal specifically with this problem:

struct Person { name: String, age: u8, } #[derive(o2o)] #[o2o(from_owned(Person))] struct PersonDto { name: String, #[o2o(as_type(u8))] age: u64, } 

This will generate following code automatically:

impl std::convert::From<Person> for PersonDto { fn from(value: Person) -> PersonDto { PersonDto { name: value.name, age: value.age as u64, } } } 

It can generate implementations for From, Into and custom IntoExisting traits for structs, tuple structs, tuples, and can handle cases like mismatching field names, types, skipping fields, nested structs, nested collections, 'uneven' structs, wrapping structs etc. It is also designed to be applicable on any side of the mapping.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.