#proc-macro #tui #macro-derive #apps #productivity #struct #syntax

r3bl_rs_utils_macro

在实现自定义 derive 时,将属性读取到结构体中的过程宏库的内部支持。由 https://crates.io/crates/r3bl_rs_utils 中的工作区使用。

26 个版本

0.9.9 2024年4月16日
0.9.8 2023年12月23日
0.9.7 2023年10月22日
0.9.2 2023年4月21日
0.7.8 2022年7月7日

#497过程宏

Download history 4162/week @ 2024-05-03 2604/week @ 2024-05-10 2524/week @ 2024-05-17 2886/week @ 2024-05-24 2562/week @ 2024-05-31 2443/week @ 2024-06-07 2672/week @ 2024-06-14 3288/week @ 2024-06-21 3912/week @ 2024-06-28 4086/week @ 2024-07-05 3189/week @ 2024-07-12 2368/week @ 2024-07-19 2462/week @ 2024-07-26 1910/week @ 2024-08-02 1614/week @ 2024-08-09 1253/week @ 2024-08-16

7,652 每月下载量
7 Crates 中使用(直接使用 3 个)

Apache-2.0

83KB
1K SLoC

上下文

R3BL TUI & 开发

我们正在努力构建Rust中的命令行应用程序,这些应用程序具有丰富的文本用户界面(TUI)。我们希望利用终端作为提高生产力的地方,并为其构建各种精彩的应用程序。

  1. 🔮 我们不仅构建一个应用程序,而是构建一个库,以启用任何类型的丰富 TUI 开发,并且有一个独特的转折:采用在移动和前端 Web 开发世界中表现良好的概念,并为 TUI 和 Rust 重新构想。

    • 比如 React、JSX、CSS 和 Redux,但使其全部异步(它们可以通过 Tokio 并行和并发运行)。
    • 甚至运行主事件循环的线程也不会阻塞,因为它也是异步的。
    • 使用过程宏创建 DSL 来实现 CSS 和 JSX。
  2. 🌎 我们正在构建应用程序以提高开发者的生产力和工作流程。

    • 这里的想法不是在 Rust 中重新构建 tmux(将多个进程复用到单个终端窗口)。而是构建一套集成的“应用程序”(或“任务”),它们在同一个进程中运行,并将渲染到单个终端窗口。
    • 在这个终端窗口内部,我们可以实现诸如“app”切换、路由、平铺布局、堆叠布局等功能,以便我们能够管理大量在同一进程、同一窗口中运行的紧密集成的TUI(文本用户界面)应用程序。因此,您可以想象,所有这些“app”都共享应用程序状态(即在Redux存储中)。每个“app”也可能有自己的Redux存储。
    • 以下是我们想要构建的“app”类型的一些示例
      1. 多用户带语法高亮的文本编辑器
      2. 与GitHub问题的集成
      3. 与日历、电子邮件、联系人API的集成

r3bl_rs_utils_macro

这个crate与上面描述的第一个内容相关。它提供了大量有用的功能来帮助您构建TUI(文本用户界面)应用程序,以及所有Rustaceans 🦀 都可以享受的通用优雅和人体工程学 🎉

过程式

所有过程式宏都组织在3个crate中 使用内部或核心crate:公共crate、内部或核心crate和过程式宏crate。

style!宏

以下是一个宏的示例

style! {
  id: "my_style",          /* Optional. */
  attrib: [dim, bold]      /* Optional. */
  padding: 10,             /* Optional. */
  color_fg: TuiColor::Blue, /* Optional. */
  color_bg: TuiColor::Red,  /* Optional. */
}

color_fgcolor_bg可以接受以下任何一种

  1. 颜色枚举值。
  2. Rgb值。
  3. 变量持有上述任一种。

Builder derive宏

此derive宏通过注释结构体或枚举来生成构建器,它对泛型有完全支持。它可以这样使用。

#[derive(Builder)]
struct Point<X, Y>
where
  X: std::fmt::Display + Clone,
  Y: std::fmt::Display + Clone,
{
  x: X,
  y: Y,
}

let my_pt: Point<i32, i32> = PointBuilder::new()
  .set_x(1 as i32)
  .set_y(2 as i32)
  .build();

assert_eq!(my_pt.x, 1);
assert_eq!(my_pt.y, 2);

使结构安全地共享和修改!

这个类似于函数的宏(带有自定义语法)使得管理结构的可共享性和内部可变性变得容易。我们称这种模式为“事物”的“管理器”。

🪄您可以在这里了解所有关于它的信息。

  1. 此结构被包装在一个RwLock中,以实现线程安全。
  2. 然后将其包装在一个Arc中,这样我们就可以在线程之间共享它。
  3. 此外,它与Tokio一起工作,使其完全异步。它还完全支持泛型和可选的where子句的特质界限。

以下是一个非常简单的用法示例

make_struct_safe_to_share_and_mutate! {
  named MyMapManager<K, V>
  where K: Default + Send + Sync + 'static, V: Default + Send + Sync + 'static
  containing my_map
  of_type std::collections::HashMap<K, V>
}

以下是一个异步示例。

#[tokio::test]
async fn test_custom_syntax_no_where_clause() {
  make_struct_safe_to_share_and_mutate! {
    named StringMap<K, V>
    // where is optional and is missing here.
    containing my_map
    of_type std::collections::HashMap<K, V>
  }

  let my_manager: StringMap<String, String> = StringMap::default();
  let locked_map = my_manager.my_map.read().await;
  assert_eq!(locked_map.len(), 0);
  drop(locked_map);
}

使安全异步函数包装器!

这个类似于函数的宏(带有自定义语法)使得管理异步函数和lambda的共享变得容易。它们应该在线程之间安全共享,并且应该支持调用或创建。

🪄您可以在这里了解如何编写过程式宏。

  1. 生成一个结构体,该结构体将给定的函数或lambda包装在Arc<RwLock<>>中,以实现线程安全和内部可变性。
  2. 生成一个get()方法,这使得在线程之间共享此结构体成为可能。
  3. 生成一个from()方法,这使得从函数或lambda创建此结构体变得容易。
  4. 生成一个spawn()方法,这使得可以使用Tokio异步地创建包含的函数或lambda成为可能。
  5. 生成一个invoke()方法,这使得可以同步调用包含的函数或lambda成为可能。

以下是如何使用此宏的示例。

use r3bl_rs_utils::make_safe_async_fn_wrapper;

make_safe_async_fn_wrapper! {
  named SafeMiddlewareFnWrapper<A>
  containing fn_mut
  of_type FnMut(A) -> Option<A>
}

以下是一个另一个示例。

use r3bl_rs_utils::make_safe_async_fn_wrapper;

make_safe_async_fn_wrapper! {
  named SafeSubscriberFnWrapper<S>
  containing fn_mut
  of_type FnMut(S) -> ()
}

依赖于此的其它crate

这个包是 r3bl_rs_utils 包("主要" 库)的依赖项。

问题、评论、反馈和PR

请将任何问题报告给 问题跟踪器。如果您有任何功能请求,也请随时添加👍。

依赖项

~12–22MB
~210K SLoC