3个不稳定版本

0.2.0 2022年12月1日
0.1.1 2020年10月27日
0.1.0 2020年10月27日

#198#interactive

Download history 479/week @ 2024-03-14 614/week @ 2024-03-21 835/week @ 2024-03-28 607/week @ 2024-04-04 570/week @ 2024-04-11 399/week @ 2024-04-18 240/week @ 2024-04-25 348/week @ 2024-05-02 307/week @ 2024-05-09 380/week @ 2024-05-16 466/week @ 2024-05-23 816/week @ 2024-05-30 469/week @ 2024-06-06 624/week @ 2024-06-13 498/week @ 2024-06-20 409/week @ 2024-06-27

每月2,063次下载
用于 rusteval

MIT/Apache

21KB
460

rusteval

github Crates.io docs.rs

此crate提供特性和宏,使您的应用程序的结构体和函数具有交互性。

使用#[derive(Interactive)]注释结构体,使用#[Methods]注释结构体的方法,以及使用#[Function]注释自由函数,将实现一组特性,允许您像Rust有REPL一样访问它们。

将此crate用作“打印调试”或作为便捷的测试API的替代方案。

此crate与no_std兼容,因此您可以使用它与嵌入式设备交互,并通过USB或UART连接闪烁LED。

用法

  • 使用InteractiveMethodsFunction注释您想访问的所有内容
  • 定义一个新的结构体,该结构体拥有或持有您想访问的对象的引用
  • 为它推导InteractiveRoot
  • 使用特性的方法评估一个字符串(最简单的是eval_to_string,但其他方法允许更自定义的行为)
  • 访问字段将给出它的调试表示
  • 调用函数或方法将解析其参数,并给出其返回值的调试表示

由于这个crate大量使用了Debug特质,因此提供了一个辅助宏PartialDebug。它为结构体实现Debug,用占位符替换所有未实现Debug的字段。

CLI使用方法

提供了诸如get_all_field_names之类的函数。这使得实现自动完成等功能成为可能。

查看自动完成示例,了解如何使用rustyline crate来完成此操作。

示例

use rusteval::{Interactive, Methods, InteractiveRoot, Function, PartialDebug};

#[derive(Default)]
struct NoDebug;

#[derive(Interactive, PartialDebug, Default)]
struct ChildStruct {
    last_sum: f32,
    no_debug: NoDebug,
}

#[Methods]
impl ChildStruct {
    fn add(&mut self, a: f32, b: f32) -> f32 {
        self.last_sum = a + b;
        self.last_sum
    }
}

#[derive(Interactive, Debug, Default)]
struct ParentStruct {
    child: ChildStruct,
}

#[derive(InteractiveRoot, Debug, Default)]
struct Root {
    parent: ParentStruct,
}

#[Function]
fn split_str_at(s: &str, mid: usize) -> (&str, &str) {
    s.split_at(mid)
}

let mut root = Root::default();
assert_eq!(root.eval_to_string("parent.child.add(4.2, 6.9)"), "11.1");
assert_eq!(root.eval_to_string("parent.child"), "ChildStruct { last_sum: 11.1, no_debug: Unknown }");
// split_str_at("foobar", 3) => ("foo", "bar")
assert_eq!(root.eval_to_string("split_str_at(\"foobar\", 3)"), "(\"foo\", \"bar\")");

工作原理

这个crate使用了不稳定的specialization特性,因此它只在nightly版本中可用。

在所有类型上实现了try_as_interactive等方法。通常,该方法返回一个错误,但在特化的情况下,返回一个特质对象(在这种情况下为&dyn Interactive)。

然后,宏实现了一些类似以下这样的获取器

fn get_field<'a>(&'a self, field_name: &'a str) -> Result<'_, &dyn Interactive> {
    match field_name {
        "field1" => self.field1.try_as_interactive(),
        "field2" => self.field2.try_as_interactive(),
        _ => Err(InteractiveError::FieldNotFound {
            type_name: "Struct",
            field_name,
        }),
    }
}

请参阅宏的文档以获取更多详细信息。

当前限制

  • 只有当函数和方法的参数类型受支持时,才能将它们转换为交互式
  • 不支持枚举

许可证

根据您的选择,许可协议为Apache License, Version 2.0MIT许可证
除非您明确说明,否则,根据Apache-2.0许可证的定义,您有意提交以包含在此crate中的任何贡献,都应如上所述双许可,没有任何额外的条款或条件。

lib.rs:

rusteval crate的进程宏。请勿直接使用此crate。

依赖关系

~1.5MB
~35K SLoC