2 个版本
0.1.1 | 2019 年 3 月 20 日 |
---|---|
0.1.0 | 2019 年 3 月 19 日 |
在 #dto 中排名 8
每月下载 30 次
27KB
576 行
#[derive(Dto)]
此软件包提供了 Dto
derive,它自动将 DTO(数据传输对象)映射到实体,反之亦然。它能够为 DTO 结构实现 From
或 Into
特性,以实现转换方向。
每个 DTO 结构都可以作为 请求 或 响应,这意味着特定的 DTO 结构可以转换自实体或转换成实体。因此,应可转换成实体的 DTO 是 请求 DTO,而应从实体构建的 DTO 是 响应 DTO。
除了简单的单对单转换外,此软件包还允许在转换过程中跳过特定字段或重命名它们。更高级的功能,例如分配外部值或字段级属性,计划在下一个版本中实现。
安装和基本使用
将以下依赖项添加到 Cargo.toml
[dependencies]
dto_derive = "0.1.0"
然后通过以下方式导入 Dto
derive
use dto_derive::Dto;
并按如下方式使用它
struct Post {
...
}
#[derive(Dto)]
#[dto(entity = "Post")]
struct PostResponse {
...
}
在这种情况下,这使您能够将 Post
转换为 PostResponse
let post: Post = ...;
let post_response: PostResponse = post.into();
有关更多示例和用例,请参阅以下部分。
关联 derive 属性
-
#[dto(entity= "Entity")]
包含映射实体类型的必需属性。每个 DTO 结构必须恰好提供一次。
-
#[dto(request)]
,#[dto(response)]
可选属性用于指定转换方向,如果DTO结构名称以
...Request
或...Response
结尾,则可以省略,例如PostResponse
,否则必须提供。 -
#[dto(map= "a: b")]
可选属性,用于指定转换过程中字段名称的重新命名。对于不同的字段可以重复。
-
#[dto(skip= "a, b, c")]
可选属性,包含在转换过程中应省略的字段名称。它可能包含要跳过的多个字段,并且/或者对于不同的字段可以重复。**该属性仅对请求DTO有效**。
示例
让我们从我们的Post
实体实现开始
struct Post {
title: String,
body: String,
}
请求DTO
为了创建一个新的帖子,我们可能有一个DTO表示
#[derive(Dto)]
#[dto(entity = "Post")]
#[dto(request)]
#[dto(map = "body: content")]
#[dto(skip = "csrf_token")]
struct NewPost {
title: String,
content: String,
csrf_token: String,
}
上述DTO可以使用into()
函数从Into
特质转换到Post
实体
let newPost = NewPost {
title: String::from("Awesome post"),
content: String::from("Awesome content of awesome post."),
csrf_token: String::from("abcde"),
};
let post: Post = newPost.into();
这是因为由于Dto
派生,NewPost
DTO实现了Into
特质。
响应DTO
响应DTO可能看起来像这样
#[derive(Dto)]
#[dto(entity = "Post")]
#[dto(map = "content: body")]
struct PostResponse {
title: String,
content: String,
}
实体到PostResponse
DTO的转换可以使用into()
函数从Into
特质完成
let post = Post {
title: String::from("Awesome post"),
body: String::from("Awesome content of awesome post."),
};
let postResponse: PostResponse = post.into();
这是因为由于Dto
派生,PostResponse
DTO实现了From
特质。
内部机制
添加#[derive(Dto)]
属性意味着为给定的结构提供From
或Into
特质的自动实现。
因此,对于NewPost
DTO结构和前一个部分中的Post
实体,将自动提供以下实现(注意NewPost
DTO的请求性质)
impl Into<Post> for NewPost {
fn into(self) -> Post {
Post {
title: self.title,
body: self.content,
}
}
}
对于实际上是一个响应DTO的PostResponse
DTO,将派生相反的实现
impl From<Post> for PostResponse {
fn from(entity: Post) -> Self {
PostResponse {
title: entity.title,
content: entity.body,
}
}
}
请注意,总是提供了一个用于DTO结构的派生实现,这允许从另一个crate导入实体结构而不会违反孤儿规则。
许可证
在MIT许可证下授权(LICENSE 或 https://opensource.org/licenses/MIT)。
依赖项
~2MB
~46K SLoC