36 个版本
0.1.35 | 2020年10月2日 |
---|---|
0.1.33 | 2020年7月26日 |
0.1.32 | 2019年10月26日 |
0.1.31 | 2017年11月30日 |
0.1.9 | 2016年11月26日 |
#802 在 数据结构
在 3 crates 中使用
70KB
1.5K SLoC
Treeflection
treeflection_derive
Treeflection 在结构体、集合和原始类型树上执行存储为字符串的命令。
命令
将一个结构体中的 Vec 的 int 设置为 50 的命令如下:someHashMap["key"].someChild.anotherChild[0]:set 50
有关完整语法,请参阅命令手册
用法
必须为树中的每个类型实现 Node
特性。然后使用命令字符串创建一个新的 NodeRunner
,并将其传递给根节点的 node_step
方法。然后将 NodeRunner
传递给命令中指定的子节点,并在指定的最终子节点上执行命令。使用 treeflection_derive
crate 来为您的结构体 #[Derive(Node)] 或编写自己的处理程序。
Vec 示例
extern crate treeflection;
use treeflection::{NodeRunner, Node};
pub fn main() {
let mut test_vec = vec!(0, 413, 358, 42);
let command = "[1]:get";
let result = test_vec.node_step(NodeRunner::new(command).unwrap());
assert_eq!(result, "413");
let command = "[1]:set 1111";
let result = test_vec.node_step(NodeRunner::new(command).unwrap());
assert_eq!(result, "");
let command = "[1]:get";
let result = test_vec.node_step(NodeRunner::new(command).unwrap());
assert_eq!(result, "1111");
}
自定义结构体示例
使用treeflection_derive crate来#[Derive(Node)]您的自定义结构体或编写自己的处理器。您的结构体还需要实现Serialize、Deserialize、Default和Clone特质,以及extern crate serde_json
。这是因为serde_json用于获取/设置整个结构体。
目前必须包含use treeflection::{NodeRunner, Node, NodeToken};
,以便宏可以访问这些类型。
extern crate treeflection;
#[macro_use] extern crate treeflection_derive;
#[macro_use] extern crate serde_derive;
extern crate serde_json;
use treeflection::{NodeRunner, Node, NodeToken};
#[derive(Node, Serialize, Deserialize, Default, Clone)]
struct SolarSystem {
pub mercury: Planet,
pub earth: Planet,
pub mars: Planet,
planet_x: Planet,
}
impl SolarSystem {
pub fn new() -> SolarSystem {
SolarSystem {
mercury: Planet { radius: 2440.0 },
earth: Planet { radius: 6371.0 },
mars: Planet { radius: 3390.0 },
planet_x: Planet { radius: 1337.0 },
}
}
}
#[NodeActions(
// we want the function circumference to be accessible via treeflection by the same name
NodeAction(function="circumference", return_string),
// we want the function explode_internal_naming_scheme to be accessible via treeflection
// by the name explode and we want to ignore its return value so that it will compile despite not returning a String
NodeAction(action="explode", function="explode_internal_naming_scheme"),
)]
#[derive(Node, Serialize, Deserialize, Default, Clone)]
struct Planet {
pub radius: f32
}
impl Planet {
pub fn circumference(&self) -> String {
(self.radius * 2.0 * std::f32::consts::PI).to_string()
}
pub fn explode_internal_naming_scheme(&mut self) {
self.radius = 0.0;
}
}
pub fn main() {
let mut ss = SolarSystem::new();
// serialize the whole struct into json
let command = ":get";
let result = ss.node_step(NodeRunner::new(command).unwrap());
assert_eq!(result,
r#"{
"mercury": {
"radius": 2440.0
},
"earth": {
"radius": 6371.0
},
"mars": {
"radius": 3390.0
},
"planet_x": {
"radius": 1337.0
}
}"#);
// access properties
let command = "earth.radius:get";
let result = ss.node_step(NodeRunner::new(command).unwrap());
assert_eq!(result, "6371");
// call methods on the struct
let command = "earth:circumference";
let result = ss.node_step(NodeRunner::new(command).unwrap());
assert_eq!(result, "40030.176");
let command = "earth:explode";
let result = ss.node_step(NodeRunner::new(command).unwrap());
assert_eq!(result, "");
assert_eq!(ss.earth.radius, 0.0);
// private properties are not accessible via treeflection
let command = "planet_x:get";
let result = ss.node_step(NodeRunner::new(command).unwrap());
assert_eq!(result, "SolarSystem does not have a property 'planet_x'");
}
贡献
这个库是为Canon Collision的具体需求而设计的。欢迎提交拉取请求,但如果更改与Canon Collision的需求相冲突,您将只能坚持使用自己的分支。:)
依赖关系
~1.1–2MB
~42K SLoC