#命令行 #开发者 #应用程序 #框架 #会话 #命令行应用程序

starbase

构建高性能命令行应用程序和开发者工具的框架

41 个版本 (6 个破坏性更新)

0.8.2 2024年7月27日
0.7.2 2024年6月6日
0.5.2 2024年3月29日
0.2.12 2023年12月26日
0.2.0 2023年7月26日

#206开发工具

Download history 494/week @ 2024-05-03 191/week @ 2024-05-10 236/week @ 2024-05-17 500/week @ 2024-05-24 627/week @ 2024-05-31 1042/week @ 2024-06-07 551/week @ 2024-06-14 715/week @ 2024-06-21 560/week @ 2024-06-28 591/week @ 2024-07-05 536/week @ 2024-07-12 599/week @ 2024-07-19 667/week @ 2024-07-26 601/week @ 2024-08-02 415/week @ 2024-08-09 762/week @ 2024-08-16

每月下载 2,569
用于 2 crates

MIT 许可证

38KB
739

starbase

Crates.io Crates.io

构建高性能命令行应用程序和开发者工具的应用程序框架。

用法

应用程序使用基于会话的方法,其中会话对象包含整个应用程序生命周期所需的数据。

创建一个 App,可选地设置诊断 (miette) 和跟踪 (tracing),然后使用提供的会话运行应用程序。需要可变会话,因为会话可以在每个 阶段 中被修改。

use starbase::{App, MainResult};
use crate::CustomSession;

#[tokio::main]
async fn main() -> MainResult {
  let app = App::default();
  app.setup_diagnostics();

  let mut session = CustomSession::default();

  app.run(&mut session, |session| async {
    // Run CLI
    Ok(())
  }).await?;

  Ok(())
}

会话

会话必须实现 AppSession 特性。这个特性提供了 4 个可选方法,每个方法代表应用程序生命周期中的不同 阶段

use starbase::{AppSession, AppResult};
use std::path::PathBuf;
use async_trait::async_trait;

#[derive(Clone)]
pub struct CustomSession {
  pub workspace_root: PathBuf,
}

#[async_trait]
impl AppSession for CustomSession {
  async fn startup(&mut self) -> AppResult {
    self.workspace_root = detect_workspace_root()?;
    Ok(())
  }
}

会话 必须 可克隆 并且Send + Sync 兼容。我们在创建 tokio 任务时克隆会话。如果您想跨线程持久化数据,请使用 ArcRwLock 和其他机制包装会话属性。

阶段

应用程序被划分为阶段,其中每个阶段将在进入下一个阶段之前被处理和完成。以下阶段可用:

  • 启动 - 注册、设置或加载初始会话状态。
    • 示例:加载配置、检测工作区根目录、加载插件
  • 分析 - 分析当前环境,更新状态,并准备执行。
    • 示例:生成项目图、加载缓存、登录服务
  • 执行 - 执行主要业务逻辑 (App#run)。
    • 示例:处理依赖图、运行生成器、检查新版本
  • 关闭 - 在整个生命周期的成功完成时或特定阶段失败时进行清理和关闭。
    • 示例:清理临时文件,关闭服务器

如果一个会话实现了 AppSession#execute 特性方法,它将与 App#run 方法并行运行。

如何

错误处理

错误和诊断由 miette 包提供。应用程序的所有层都返回 miette::Result 类型(通过 AppResult)。这使得错误可以轻松转换为诊断,并且 miette 可以自动将错误和恐慌渲染到终端。

要利用这一点,请更新您的 main 函数以返回 MainResult

use starbase::{App, MainResult};

#[tokio::main]
async fn main() -> MainResult {
  let app = App::default();
  app.setup_diagnostics();
  app.setup_tracing_defaults();

  // ...

  Ok(())
}

为了最大限度地利用错误和诊断,最好(也是建议)使用 thiserror 包。

use miette::Diagnostic;
use thiserror::Error;

#[derive(Debug, Diagnostic, Error)]
pub enum AppError {
    #[error(transparent)]
    #[diagnostic(code(app::io_error))]
    IoError(#[from] std::io::Error),

    #[error("Systems offline!")]
    #[diagnostic(code(app::bad_code))]
    SystemsOffline,
}

注意事项

返回的 Err 必须首先转换为诊断。有两种方法可以实现这一点

#[system]
async fn could_fail() {
  // Convert error using into()
  Err(AppError::SystemsOffline.into())

  // OR use ? operator on Err()
  Err(AppError::SystemsOffline)?
}

依赖关系

~7–18MB
~227K SLoC