You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
code refactoring changes with macro attributes added to mapped existing fields (#12)
* code refactoring changes with properties added to mapped fields
* code changes for previous review
* remove unnecessary import prefix
* bump cargo dependencies
* adding custom macro attributes for mapping fields
* adding rustfmt.toml for default source code formatting config
* replacing unstrigify by syn parse_sr
* update dto example with custom attributes
* Update README.md
* Fix README.md typo
* update README.md with dependencies removal
* adjust README.md with more detail explanation
* bump dto_mapper version from 0.2.0 to 0.3.0
Adding change log to track features and history
Copy file name to clipboardexpand all lines: README.md
+37-16
Original file line number
Diff line number
Diff line change
@@ -28,13 +28,15 @@ If we have to load a 'user' record from a database, we wouldn't want to send all
28
28
This is where DTO Mapper Library comes handy.
29
29
30
30
# Installation
31
-
**_dto_mapper_** library depends on **_unstringify_** and **_derive_builder_** which implements builder pattern for dto objects resulted from the dto mappers.
31
+
**_dto_mapper_** library depends **_derive_builder_** which implements builder pattern for dto objects resulted from the dto mappers.
32
32
By default, it generate builder for the dtos.
33
+
Early versions of the dto_mapper used to depend on **_unstringify_** crate. It is no longer required anymore and has been removed.
34
+
If you are using this current version. You can remove this dependency from your project.
35
+
33
36
You can use this instruction to install the latest version of **dto_mapper** library to your project
34
37
```shell
35
38
cargo add derive_builder
36
39
cargo add dto_mapper
37
-
cargo add unstringify
38
40
```
39
41
And import it to the rust source file you need to use it:
40
42
```rust
@@ -44,11 +46,12 @@ use dto_mapper::DtoMapper;
44
46
More details on how to use derive_builder crate here: https://crates.io/crates/derive_builder
45
47
46
48
# Example
47
-
Let's say we want to create 3 special entities for our application
49
+
Let's say we want to create special struct derived from a base existing **struct User** for our application
48
50
- LoginDto that will contain only 2 fields from **User** such as _**username**_ and _**password**_. we would like to rename _**username**_ to _**login**_ in LoginDto
49
51
- ProfileDto that will contain all fields from **User** and will ignore only the **password** field.
50
52
- PersonDto that will contain only 3 fields from **User** such as _**firstname**_, _**lastname**_, and _**email**_. But we would like to make the _**email**_ field optional such that its final data type will be _**Option<T>**_. That is if email is **String** from User, it will result in _**Option<String>**_
51
-
53
+
- CustomDtoWithAttribute that will create a new field called name which will be computed from two existing fields on the struct.
54
+
We will add as well serde macro attributes for serialization on the struct, on an existing and a new struct field as well
52
55
It takes only those lines below to get this work done. And the conversion are being done automatically between one dto type to the original struct and vice versa.
53
56
54
57
```rust
@@ -62,7 +65,6 @@ It takes only those lines below to get this work done. And the conversion are be
62
65
#[allow(unused)]
63
66
usestd::str::FromStr;
64
67
#[allow(unused)]
65
-
useunstringify::unstringify;
66
68
67
69
fnconcat_str(s1:&str, s2:&str) ->String {
68
70
s1.to_owned() +""+s2
@@ -81,13 +83,19 @@ It takes only those lines below to get this work done. And the conversion are be
["#[serde(rename = \"renamed_name\")]"], // attribute of fields
93
+
),
94
+
(
95
+
"hidden_password: String",
96
+
r#""*".repeat( self.password.len() )"#
97
+
),
98
+
],
91
99
macro_attr=["serde(rename_all = \"UPPERCASE\")"] // atriibute of struct
92
100
)]
93
101
structUser{
@@ -167,6 +175,15 @@ pub struct PersonDto {
167
175
pubfirstname:String,
168
176
publastname:String,
169
177
} // size = 72 (0x48), align = 0x8
178
+
179
+
#[serde(rename_all ="UPPERCASE")]
180
+
pubstructCustomDtoWithAttribute {
181
+
#[serde(rename ="email_address")]
182
+
pubemail:Option<String>,
183
+
#[serde(rename ="full_name")]
184
+
pubname:String,
185
+
pubhidden_password:String,
186
+
}
170
187
```
171
188
172
189
@@ -203,7 +220,8 @@ impl Into<CustomDto> for User {
203
220
You can install 'expand' binary crate and use ***cargo expand*** command in order to print out the DTO structures generated as shown above:
204
221
```shell
205
222
cargo install expand
206
-
cargo expand
223
+
#you can try this command from this library root directory
224
+
cargo expand dto_example
207
225
```
208
226
# Description of macro derive and attributes for Dto Mapper
209
227
First, DTO Mapper library requires that the source struct implements Default traits as the library relies on it to implement Into Traits for conversion between DTO and Source struct.
@@ -217,18 +235,21 @@ struct SourceStruct{ }
217
235
-**Required fields** will result in build errors if not present.
218
236
-**dto** : name for the dto that will result into a struct with the same name. Example : `dto="MyDto"` will result into a struct named **MyDto**.
219
237
dto names must be unique. Otherwise, it will result into build errors.
220
-
-**map** : an array of field names from the original struct to include or map to the new dto as fields. `map=[("fieldname:new_fieldname", required_flag )]`.
238
+
-**map** : an array of field names from the original struct to include or map to the new dto as fields. `map=[("fieldname:new_fieldname", required_flag, ["field_attribute", "field_attribute"] )]`.
221
239
`fieldname:new_fieldname` will rename the source field to the new one. It is not mandatory to rename. you can have `map=[("fieldname",true)]`
222
240
`required_flag` can be true or false. if required_flag is false it will make the field an **Option** type in the dto.
241
+
`field_attributes` are lists of macro attributes to be added to a particular field. For Example map=[("fieldname",true, ["#[serde(rename = \"full_name\")]"] )].
223
242
224
243
if `required_flag` is set to true, the destination dto field will be exactly of the same type with the source one in the struct.
225
244
-**Optional fields**
226
245
-**ignore** : an array of fieldnames not to include in the destination dtos. `ignore=["field1", "field1"]`
227
246
if **ignore** is present , then **map** field becomes optional. Except if needed rename destination fields for the dto
228
-
-**derive** : a list of of macro to derive from. `derive=(Debug,Clone)`
247
+
-**derive** : list of of macro to derive from. `derive=(Debug,Clone)`
229
248
-**no_builder**: a boolean flag to turn on or off builders for the dto. Default value is **_false_**. If the Dto name is "MyDto" , the builder will create a struct named "MyDtoBuilder" that can be used to build "MyDto" struct.
230
-
-**new_fields** : an array of declaration of new field names to include to the resulted dto structure. `new_fields=[("fieldname:type"), ("initialize_expression") )]`.
249
+
-**macro_attr**: an array of macro attributes to be added on the top of the resulted **struct**. For example : macro_attr=["serde(rename_all = \"UPPERCASE\")"]
250
+
-**new_fields** : an array of declaration of new field names to include to the resulted dto structure. `new_fields=[("fieldname:type"), ("initialize_expression") ), ["macro_attribute","macro_attribute"]`.
231
251
`fieldname:type` will create a new field with the `fieldname` specified and the `type`. It is not mandatory to rename. you can have `map=[("fieldname",true)]`
232
252
`initialize_expression` is used an initialize value or expression to use when converting the original structure to the dto.
233
-
For instance `new_fields=[("name:String"), ("concat_str(self.firstname,self.lastname)") )]` will create a new field in the dto called `name` which will be initialized with the concatenation of the original struct `firstname` and `lastname` fields. See the example above.
253
+
`macro_attribute` will add a macro declaration on the top of this field. it is an array of attributes. It is **optional** and not required.
254
+
For instance `new_fields=[( "name:String", "concat_str(self.firstname,self.lastname)" , ["#[serde(rename = \"full_name\")]"] )]` will create a new field in the dto called `name` which will be initialized with the concatenation of the original struct `firstname` and `lastname` fields. See the example above.
234
255
**I would strongly suggest to use function as `initialize_expression` for more complex scenarios in case parsing is failing when writing complex inline expression directly. This will reduce code complexity!!**
0 commit comments