如何借助serde获取结构体字段类型信息以生成数据库表结构?
问题:利用Serde实现结构体与数据库表的双向转换
需求背景
我正在开发一个本地关系型数据库系统,希望借助Serde自动实现HashMap与数据库表的双向转换。目标处理的简单结构体示例如下:
struct SampleObject { name: String, age : Option<u32>, job : Option<String> }
需要实现类似以下的函数:
pub fn from_serde_map<V>( table_name: &str, primary_key_name: &str, data: HashMap<String, V>, ) -> Result<Table> where V: Serialize,
该函数需利用serde::Value将结构体转换为包含字段类型信息与列约束的表,其中非Option类型字段需添加NOT_NULL约束。
我仅需支持扁平结构体,字段类型范围包括:简单数值类型、String、Boolean、上述类型的Option,进阶目标还需支持Vec<String>、简单枚举、Vec<简单枚举>。
初步尝试与问题
我最初尝试通过首个Map元素构建表头,代码如下:
use serde::{Deserialize, Serialize}; #[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)] struct SampleObject { name: String, age : Option<u32>, job : Option<String> } pub fn explore_item<V>( v : V ) where V: Serialize, { let header_object = serde_json::to_value(v) .unwrap() .as_object() .unwrap() .clone(); for (k, v) in header_object.into_iter() { let as_value = serde_json::to_value(v).unwrap(); println!("{}: {:?}", k, as_value); } } #[test] fn call_explore_item() { let adam = SampleObject { name: "Adam".to_string(), age: None, job : Some("Gardener".to_string()) }; explore_item(adam); }
输出结果:
age: Null job: String("Gardener") name: String("Adam")
但这个方案存在两个核心问题:
- 依赖
V的实际实例,无法处理空HashMap的情况; Option类型字段丢失内部类型信息:job与name显示信息一致,age为None时无法表明它是u32类型的None。
疑问与求助
我曾想过通过类似(V as Serialize)::typeAt("crime")的方式获取类型信息,但没能实现。也尝试过部分json_schema相关的crate,但觉得功能过于复杂。想请教是否有更简便的实现方式,还是必须自行编写derive macros?
补充说明
我需要获取SampleObject这类简单结构体的字段类型信息,以此生成表的表头信息。例如定义ColType枚举(包含StringType、U32Type等变体),最终SampleObject对应的表需包含:
name列:类型StringType,添加NotNull约束;age列:类型U32Type;job列:类型StringType;
(name因非Option类型而添加NotNull约束)
内容的提问来源于stack exchange,提问作者Edward Peters
相关产品推荐
相关产品推荐

