根据查看的代码, #[track] 宏是一个属性宏,主要为结构体自动生成跟踪状态变化的功能。它生成的主要函数包括:
1. 1.构造函数
- new() : 创建结构体实例,初始化所有字段
2. 2.字段设置方法
- 为每个标记了 #[track(setter)] 的字段生成 set_字段名() 方法
- 支持数值类型的范围检查(通过 min / max 属性)
- 对于BTreeMap类型字段生成特殊的setter方法
3. 3.JSON交互方法
- set_from_json(&mut self, json: &serde_json::Value) : 从JSON对象更新结构体字段
- get_full_data(&self) -> serde_json::Value : 获取所有字段的完整JSON表示
4. 4.状态跟踪方法
- get_changed(&self) -> serde_json::Map<String, serde_json::Value> : 获取所有发生变化的字段
- get_changed_of_save(&self) -> serde_json::Map<String, serde_json::Value> : 获取需要保存的变化字段(标记了 nvm 的字段)
- clear_changed(&mut self) : 清除变化标记
- clear_changed_of_save(&mut self) : 清除需要保存的变化标记
此外,该宏还支持嵌套跟踪(通过 nested 属性),可以递归跟踪嵌套结构体的变化。
宏通过在结构体中添加两个内部字段来实现跟踪功能:
- changed : 记录所有发生变化的字段
- changed_of_save : 记录需要持久化存储的变化字段
这个宏主要用于需要跟踪数据变化状态、支持JSON序列化/反序列化以及可能需要数据持久化的场景,特别适合配置管理、状态监控等应用。
# track 宏支持的标记及其用途详解
通过分析代码,我发现 track 宏支持多种标记来控制字段的行为和功能。这些标记定义在 FieldAttributes 结构体中,并在编译时由宏处理以生成相应的代码。以下是每个标记的详细说明:
## 1. setter
类型 : bool (默认为 false ) 用途 : 标记字段是否需要生成 setter 方法 实现 :
- 当设置为 true 时,宏会为该字段生成名为 set_字段名 的 setter 方法
- setter 方法会执行值比较、范围检查(如果定义了 min/max)以及变更跟踪逻辑
- 对于 BTreeMap 类型字段,会生成特殊的 setter 方法处理复杂的集合操作
示例 : #[track(setter)]
## 2. nvm (Non-Volatile Memory)
类型 : bool (默认为 false ) 用途 : 标记字段是否需要持久化存储 实现 :
- 当设置为 true 时,字段变更会同时记录到 changed 和 changed_of_save 集合中
- 未标记的字段变更只会记录到 changed 集合中
- get_changed_of_save() 方法用于获取需要持久化的变更
示例 : #[track(setter, nvm)]
## 3. min
类型 : Option<NumberValue> (支持整数和浮点数) 用途 : 设置数值类型字段的最小值 实现 :
- 在 setter 方法中生成范围检查代码,确保输入值不小于指定的最小值
- 内部使用 value.max(min_value) 实现
- 支持正负整数值和浮点数值
示例 : #[track(setter, min = 0)] 或 #[track(setter, min = -10.5)]
## 4. max
类型 : Option<NumberValue> (支持整数和浮点数) 用途 : 设置数值类型字段的最大值 实现 :
- 在 setter 方法中生成范围检查代码,确保输入值不大于指定的最大值
- 内部使用 value.min(max_value) 实现
- 支持正负整数值和浮点数值
示例 : #[track(setter, max = 100)] 或 #[track(setter, max = 99.9)]
## 5. json_setable
类型 : bool (默认为 false ) 用途 : 标记字段是否可以通过 set_from_json 方法从 JSON 数据中设置 实现 :
- 当设置为 true 且同时设置了 setter 时,该字段会被包含在 set_from_json 方法的处理逻辑中
- JSON 对象中的键名使用字段名的小驼峰形式(camelCase)
- 对于 bool 类型有特殊处理,可以接受 boolean 值或非零数字值
示例 : #[track(setter, json_setable)]
## 6. num
类型 : Option<usize> 用途 : 用于 BTreeMap 类型字段,指定初始元素数量 实现 :
- 在结构体初始化时,会创建指定数量的初始 BTreeMap 条目
- 键名格式为 "字段名的小驼峰形式 + 序号" (如 "config1", "config2")
- 值通过调用 new() 方法创建对应类型的实例
示例 : #[track(setter, num = 3)]
## 7. nested
类型 : bool (默认为 false ) 用途 : 标记嵌套的子跟踪字段 实现 :
- 当设置为 true 时,表示该字段本身也是一个使用 track 宏的结构体
- 在初始化时使用 Type::new() 而不是 Default::default()
- 在 set_from_json 、 get_full_data 、 get_changed 和 get_changed_of_save 方法中会递归处理嵌套字段
- 嵌套字段的变更会被收集并以嵌套的 JSON 对象形式返回
示例 : #[track(nested)]
## 8. init
类型 : Option<InitValue> (支持整数、浮点数和字符串) 用途 : 指定字段的初始值 实现 :
- 在结构体初始化时为字段设置指定的初始值
- 支持整数、浮点数和字符串类型的初始值
- 会根据值类型自动进行适当的类型转换
- 优先级高于 num 标记和默认初始化
示例 :
- #[track(init = 42)]
- #[track(init = 3.14)]
- #[track(init = "default_value")]
使用场景示例
下面是一些常见的使用场景示例:
1.需要持久化的配置字段 :
#[track(setter, nvm, min = 0, max = 100)]
pub temperature: i32,
2.嵌套配置结构 :
#[track(nested)]
pub advanced_settings: AdvancedSettings,
3.JSON可设置的字符串字段 :
#[track(setter, json_setable, init = "default")]
pub name: String,
4.初始化为多个条目的BTreeMap :
#[track(setter, json_setable, num = 5)]
pub parameters: BTreeMap<String, Parameter>,