#tree #reflection #treeflection

treeflection_derive

Treeflection库的#[derive(Node)]宏

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 中使用

MIT 许可证

27KB
593 代码行

Treeflection 在一个结构体、集合和原始类型的树中执行存储为字符串的命令。构建状态 Crates.io 文档

treeflection_derive Crates.io 文档

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