23个版本
0.4.0 | 2019年8月14日 |
---|---|
0.3.2 | 2018年9月14日 |
0.3.0 | 2018年5月23日 |
0.2.0 | 2018年1月14日 |
0.1.8 | 2016年11月30日 |
#88 in #reflection
46 每月下载量
在 2 crates 中使用
27KB
593 代码行
Treeflection 在一个结构体、集合和原始类型的树中执行存储为字符串的命令。
treeflection_derive
Treeflection 在结构体、集合和原始类型的树中执行存储为字符串的命令。
命令
将一个结构体中HashMap内另一个结构体中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 traits,以及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的具体需求设计的。欢迎提交pull请求,但如果更改与Canon Collision的需求相冲突,您将只能使用自己的分支。:)
依赖项
~1.7–2.4MB
~53K SLoC