Rust字典结构自动生成库dict_derive的使用,简化Rust数据结构与字典映射的宏派生实现

Rust字典结构自动生成库dict_derive的使用

dict_derive是一个简化Rust与Python字典互操作的派生宏库,它实现了PyO3的FromPyObjectIntoPy<PyObject>特性,可以自动在Rust结构体和Python字典之间进行转换。

基本用法

首先需要在Cargo.toml中添加依赖:

[dependencies]
pyo3 = { version = "0.22", features = ["gil-refs"] }
dict_derive = "0.6"

然后通过派生宏为结构体添加转换能力:

use dict_derive::{FromPyObject, IntoPyObject};

#[derive(FromPyObject, IntoPyObject)]
struct User {
    name: String,
    email: String,
    age: u32,
}

完整示例

以下是一个完整的Rust-Python交互示例,展示了如何使用dict_derive进行双向转换:

// Cargo.toml配置:
// [dependencies]
// pyo3 = { version = "0.22", features = ["gil-refs", "extension-module"] }
// dict_derive = "0.6"

use dict_derive::{FromPyObject, IntoPyObject};
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

// 定义可转换的结构体
#[derive(FromPyObject, IntoPyObject, Debug)]
struct User {
    name: String,    // 用户名
    email: String,   // 电子邮箱
    age: u32,        // 年龄
    is_active: bool, // 是否活跃
}

// 处理用户信息的函数
#[pyfunction]
fn process_user(user: User) -> PyResult<String> {
    println!("接收到用户: {:?}", user);
    let status = if user.is_active { "活跃" } else { "不活跃" };
    Ok(format!("已处理: {} ({}岁, {}) - {}", 
        user.name, user.age, status, user.email))
}

// 创建默认用户的函数
#[pyfunction]
fn create_default_user() -> PyResult<User> {
    Ok(User {
        name: "默认用户".to_string(),
        email: "default@example.com".to_string(),
        age: 30,
        is_active: true,
    })
}

// Python模块初始化
#[pymodule]
fn rust_python_dict(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(process_user, m)?)?;
    m.add_function(wrap_pyfunction!(create_default_user, m)?)?;
    Ok(())
}

Python端使用示例

编译为Python模块后,可以这样使用:

import rust_python_dict

# 从Rust接收字典
user_dict = rust_python_dict.create_default_user()
print(user_dict)
# 输出: {'name': '默认用户', 'email': 'default@example.com', 'age': 30, 'is_active': True}

# 向Rust发送字典
result = rust_python_dict.process_user({
    'name': '张三',
    'email': 'zhangsan@example.com',
    'age': 25,
    'is_active': False
})
print(result)
# 输出: 已处理: 张三 (25岁, 不活跃) - zhangsan@example.com

版本兼容性

  • PyO3 0.7.0或更低版本: 使用dict_derive 0.1
  • PyO3 0.8-0.10: 使用dict_derive 0.2
  • PyO3 0.11-0.13: 使用dict_derive 0.3
  • PyO3 0.14-0.19: 使用dict_derive 0.4
  • PyO3 0.20: 使用dict_derive 0.5
  • PyO3 0.22: 使用dict_derive 0.6

1 回复

Rust字典结构自动生成库dict_derive使用指南

dict_derive是一个Rust宏派生库,它可以自动为你的数据结构生成字典映射功能,简化Rust数据结构与字典之间的转换。

安装

Cargo.toml中添加依赖:

[dependencies]
dict_derive = "0.1"

基本用法

1. 派生Dict trait

use dict_derive::IntoDict;

#[derive(IntoDict)]
struct User {
    id: i32,
    name: String,
    email: String,
    is_active: bool,
}

2. 转换为字典

let user = User {
    id: 1,
    name: "Alice".to_string(),
    email: "alice@example.com".to_string(),
    is_active: true,
};

let dict = user.into_dict();
println!("{:?}", dict);
// 输出: {"id": 1, "name": "Alice", "email": "alice@example.com", "is_active": true}

高级用法

1. 自定义字段名

#[derive(IntoDict)]
struct Product {
    #[dict(rename = "product_id")]
    id: i64,
    #[dict(rename = "product_name")]
    name: String,
    price: f64,
}

2. 跳过字段

#[derive(IntoDict)]
struct Account {
    username: String,
    #[dict(skip)]
    password: String,  // 这个字段不会出现在字典中
    email: String,
}

3. 嵌套结构

#[derive(IntoDict)]
struct Address {
    street: String,
    city: String,
}

#[derive(IntoDict)]
struct Person {
    name: String,
    age: u8,
    address: Address,  // 嵌套结构也会被转换为字典
}

4. 枚举支持

#[derive(IntoDict)]
enum Status {
    Active,
    Inactive,
    Suspended,
}

#[derive(IntoDict)]
struct AccountStatus {
    user_id: i32,
    status: Status,  // 枚举会被转换为字符串表示
}

从字典创建结构体

dict_derive也支持从字典创建结构体:

use dict_derive::FromDict;

#[derive(FromDict)]
struct Config {
    host: String,
    port: u16,
    timeout: u64,
}

let dict = serde_json::json!({
    "host": "localhost",
    "port": 8080,
    "timeout": 30
});

let config = Config::from_dict(dict).unwrap();

注意事项

  1. 字段类型需要实现Into<Value>From<Value> trait
  2. 对于复杂类型,可能需要手动实现转换逻辑
  3. 与serde的Serialize/Deserialize不同,dict_derive专注于简单的字典映射

完整示例

use dict_derive::{FromDict, IntoDict};
use std::collections::HashMap;

#[derive(Debug, IntoDict, FromDict)]
struct Book {
    isbn: String,
    title: String,
    author: String,
    #[dict(rename = "pub_year")]
    year: u16,
    #[dict(skip)]
    internal_id: u32,
}

fn main() {
    let book = Book {
        isbn: "978-3-16-148410-0".to_string(),
        title: "Rust in Action".to_string(),
        author: "Tim McNamara".to_string(),
        year: 2021,
        internal_id: 12345,
    };
    
    // 转换为字典
    let dict = book.into_dict();
    println!("Book as dict: {:?}", dict);
    
    // 从字典创建
    let mut new_dict = HashMap::new();
    new_dict.insert("isbn".to_string(), "978-1-59327-828-4".into());
    new_dict.insert("title".to_string(), "The Rust Programming Language".into());
    new_dict.insert("author".to_string(), "Steve Klabnik and Carol Nichols".into());
    new_dict.insert("pub_year".to_string(), 2018.into());
    
    let new_book = Book::from_dict(new_dict).unwrap();
    println!("New book: {:?}", new_book);
}

dict_derive库特别适合需要快速在结构体和简单字典之间转换的场景,比如Web开发中的请求/响应处理、配置管理等。

回到顶部