2 个版本

0.1.1 2019 年 3 月 20 日
0.1.0 2019 年 3 月 19 日

#dto 中排名 8

每月下载 30

MIT 许可证

27KB
576

#[derive(Dto)]

Build Status

此软件包提供了 Dto derive,它自动将 DTO(数据传输对象)映射到实体,反之亦然。它能够为 DTO 结构实现 FromInto 特性,以实现转换方向。

每个 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)]属性意味着为给定的结构提供FromInto特质的自动实现。

因此,对于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许可证下授权(LICENSEhttps://opensource.org/licenses/MIT)。

依赖项

~2MB
~46K SLoC