From 56d751302878eb770934bd9dbdce3df4a48ad59d Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 3 Nov 2025 19:56:49 +0800 Subject: feat: Add sheet management commands - Add sheet list, use, exit, make, drop subcommands - Implement lazy commands: exit, use, sheets - Add sheet alias 'sh' for convenience - Add update alias 'u' for convenience - Implement sheet listing with formatted output - Add sheet creation functionality with error handling --- locales/help_docs/en.yml | 107 +++++++++---- locales/help_docs/zh-CN.yml | 97 +++++++++--- src/bin/jv.rs | 373 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 492 insertions(+), 85 deletions(-) diff --git a/locales/help_docs/en.yml b/locales/help_docs/en.yml index dc2daed..435ad21 100644 --- a/locales/help_docs/en.yml +++ b/locales/help_docs/en.yml @@ -10,11 +10,11 @@ jvv: * With great power comes great responsibility * **VAULT**: - create - Create a vault in the given directory name - init - Create a vault in the current directory + create - Create a vault in the given directory name + init - Create a vault in the current directory **QUERY**: - here - Query information about the current vault + here - Query information about the current vault **MEMBERS**: member [list|register|remove] @@ -23,7 +23,7 @@ jvv: remove - Remove a member **SERVICES**: - service listen - Run the server + service listen - Run the server Additionally, you can use jvv --help to query more detailed help! @@ -128,7 +128,7 @@ jvv: footer: | **Among them, %{num} members have registered PubKeys.** - status_key_registered: (Registered) + status_key_registered: (REGISTERED) service: listen_start: Listening for client connections in vault `%{path}` ... @@ -140,35 +140,37 @@ jv: This program connects to upstream vaults to synchronize and commit changes to local workspace files for collaborative work. **ALIASES**: - jv u - Download latest information - jv t - Track files - jv mv -a - Auto-move files - jv [in|out] - Import or export files + jv u - Download latest information + jv t - Track files + jv mv -a - Auto-move files + jv [in|out] - Import or export files **WORKSPACE**: - create - Create workspace - init - Create workspace in current directory + create - Create workspace + init - Create workspace in current directory **UPSTREAM VAULT**: - direct - Direct workspace to upstream vault - unstain - Unstain workspace, clear association + direct - Direct workspace to upstream vault + unstain - Unstain workspace, clear association **ACCOUNTS**: account [list|as|add|remove|movekey] - list - List accounts - as - Switch account in workspace - add - Add account to this computer - remove - Remove account from computer - movekey - Move private key file to specified account + list - List accounts + as - Switch account in workspace + add - Add account to this computer + remove - Remove account from computer + movekey - Move private key file to specified account **SYNC**: update - Download latest information **SHEETS**: - sheet [list|use|exit] - list - List all sheets - use - Use sheet, start work - exit - Exit sheet, clear current modifications + sheet [list|use|exit|make|drop] + list - List all sheets + use - Use sheet, start work + exit - Exit sheet, clear current modifications + make - Create a new sheet for yourself + drop - Drop the sheet for others to use **FILE TRANSFER** import - Import files from import area @@ -176,13 +178,13 @@ jv: export - Export files to other sheets **FILE OPERATIONS** - move - Safely rename files - move auto - Automatically handle local file moves or renames - track - Track and upload files to upstream vault + move - Safely rename files + move auto - Automatically handle local file moves or renames + track - Track and upload files to upstream vault **DOCUMENTATION** - docs list - List all available documentation - docs - View content of specified documentation + docs list - List all available documentation + docs - View content of specified documentation You can use jv --help to query more detailed help! @@ -201,12 +203,16 @@ jv: You need to set up accounts before interacting with upstream vaults. sheet: | - **Manage File Sheets** + **Manage Sheets** **Usage**: jv sheet list - List all sheets in the upstream workspace + jv sheet use - Use the specified sheet to start current work (automatically created if it doesn't exist) jv sheet exit - Exit current work + jv sheet make - Create a new sheet for yourself + jv sheet drop - Drop the sheet for others to use + Sheets are core concepts in JustEnoughVCS, each sheet represents an independent file collection. You can switch work between different sheets, or export files from one sheet to another. @@ -359,7 +365,7 @@ jv: Cannot recognize *`%{str}`* as a valid address, please check your input! from_just_version_control: | - **Error**: `%{err}` (This error is provided by JustEnoughVCS) + **Error**: `%{err}` (This error is from core call) account: no_user_dir: Cannot find user directory! @@ -407,7 +413,7 @@ jv: header: | **There are %{num} account(s) on this computer:** - status_has_key: (Registered) + status_has_key: (REGISTERED) move_key: Successfully moved the private key to the account directory! create: Successfully created local workspace! init: Successfully created workspace here! @@ -416,12 +422,40 @@ jv: The current workspace no longer belongs to any upstream vault, please direct to a new upstream vault before working **Tip**: Use `jv direct ` to redirect to a new upstream vault + sheet: + list: + your_sheet: | + **YOURS**: + your_sheet_item: | + %{number}. %{name} + your_sheet_item_use: | + %{number}. %{name} (CURRENT) + other_sheet: | + **OTHERS**: + other_sheet_item: | + %{number}. %{name} (AT `%{holder}`) + other_sheet_item_no_holder: | + %{number}. %{name} (NO HOLDER) + tip_has_sheet: | + You can use `jv use ` to start working + tip_no_sheet: | + **YOU HAVE NO SHEETS** + You can use `jv sheet make ` to create a new sheet + result: common: authroize_failed: | Authentication failed: %{err}! + unknown: | + Unknown result! direct: + redirected: | + Successfully redirected to upstream vault `%{upstream}`! + + redirect_failed: | + Redirection failed: %{err}! + directed_and_stained: | Successfully directed to upstream vault `%{upstream}`! Workspace has been **stained**, ready to start working! @@ -430,6 +464,19 @@ jv: Current workspace is already stained and cannot be directed to other upstream vaults with different identifiers Please use `jv unstain` to remove the stain first + same_upstream: | + Current upstream is the same as given, no need to redirect + update: success: | Synchronized to latest information! + + sheet: + make: + success: | + Successfully created sheet `%{name}`! + Upstream changed,use `jv update` to get the latest information + sheet_already_exists: | + Sheet `%{name}` already exists! + sheet_creation_failed: | + Sheet creation failed: `%{error}` diff --git a/locales/help_docs/zh-CN.yml b/locales/help_docs/zh-CN.yml index 08a44de..7fa8a43 100644 --- a/locales/help_docs/zh-CN.yml +++ b/locales/help_docs/zh-CN.yml @@ -9,11 +9,11 @@ jvv: **注意**:它能直接操作库的数据,请谨慎使用!*(能力越大,责任越大)* **创建库**: - create <名称> - 在给定的目录名称中创建库 - init - 在当前目录中创建库 + create <名称> - 在给定的目录名称中创建库 + init - 在当前目录中创建库 **查询**: - here - 查询当前库的信息 + here - 查询当前库的信息 **成员管理**: member [list|register|remove] @@ -22,7 +22,7 @@ jvv: remove <成员名称> - 移除成员 **服务**: - service listen - 运行服务端 + service listen - 运行服务端 另外,您可以使用 jvv <命令名称> --help 来查询更详细的帮助! @@ -137,12 +137,12 @@ jv: jv u 下载最新信息,jv t 追踪文件,jv mv -a 自动移动文件,jv in/out 导入或导出文件 **工作区**: - create <名称> - 创建工作区 - init - 当前目录创建工作区 + create <名称> - 创建工作区 + init - 当前目录创建工作区 **上游库**: - direct <上游地址> - 定向到工作区到上游库 - unstain - 祛色工作区,清除关联 + direct <上游地址> - 定向到工作区到上游库 + unstain - 祛色工作区,清除关联 **账户**: account [list|as|add|remove|movekey] @@ -155,27 +155,29 @@ jv: movekey <账户> <私钥> - 移动私钥文件到指定账户 **信息同步**: - update - 下载最新的信息 + update - 下载最新的信息 **表操作**: - sheet [list|use|exit] - list - 列出所有表 - use - 使用表,并开始工作 - exit - 退出表,清除当前修改 + sheet [list|use|exit|make|drop] + list - 列出所有表 + use - 使用表,并开始工作 + exit - 退出表,清除当前修改 + make - 创建新表以供自己使用 + drop - 抛弃表以供他人使用 **文件传递** - import <文件包名称> - 从导入区导入文件 - import <参照表中目录> - 从参照表导入文件 - export <文件> <表名称> - 导出文件到其他表 + import <文件包名称> - 从导入区导入文件 + import <参照表中目录> - 从参照表导入文件 + export <文件> <表名称> - 导出文件到其他表 **文件操作** - move <文件> <到> - 安全地重命名文件 - move auto - 自动处理本地文件的移动或重命名 - track <文件> - 追踪、上传文件到上游库 + move <文件> <到> - 安全地重命名文件 + move auto - 自动处理本地文件的移动或重命名 + track <文件> - 追踪、上传文件到上游库 **内建文档** - docs list - 列出所有可用的文档 - docs <文档名称> - 查看指定文档的内容 + docs list - 列出所有可用的文档 + docs <文档名称> - 查看指定文档的内容 您可以使用 jv <命令名称> --help 来查询更详细的帮助! @@ -195,14 +197,18 @@ jv: sheet: | - **管理文件表** + **管理表** **用法**: jv sheet list - 列出上游工作区的所有表 + jv sheet use <表名称> - 使用指定的表开始当前工作(不存在则自动创建) jv sheet exit - 退出当前工作 - 表是 JustEnoughVCS 中的核心概念,每个表代表一个独立的文件集合 - 您可以在不同的表之间切换工作,或者将文件从一个表导出到另一个表 + jv sheet make <表名称> - 为自己创建一张新的表 + jv sheet drop <表名称> - 将表抛弃,以供其他人使用 + + 表是 JustEnoughVCS 中的核心概念,每个表代表一块独立的文件集合 + 您可以在不同的表之间切换工作,或者将文件从一张表导出到另一张表 create: | @@ -366,7 +372,7 @@ jv: 无法将 *`%{str}`* 识别为有效地址,请检查您的输入! from_just_version_control: | - **错误**:`%{err}`(该错误由 JustEnoughVCS 提供) + **错误**:`%{err}`(该错误来自核心调用) account: no_user_dir: 无法找到用户目录! @@ -424,11 +430,39 @@ jv: 当前工作区不再属于任何上游库,请工作前定向至新的上游库 **提示**:使用 `jv direct <上游库地址>` 重新定向至新的上游库 + sheet: + list: + your_sheet: | + **你的表**: + your_sheet_item: | + %{number}. %{name} + your_sheet_item_use: | + %{number}. %{name}(当前) + other_sheet: | + **其他表**: + other_sheet_item: | + %{number}. %{name}(属于 `%{holder}`) + other_sheet_item_no_holder: | + %{number}. %{name}(无人认领) + tip_has_sheet: | + 你可以使用 `jv use <表名>` 开始工作 + tip_no_sheet: | + **没有可以编辑的表!** + 你可以使用 `jv sheet make <表名>` 创建一张新表 + result: common: authroize_failed: 身份认证失败:%{err}! + unknown: | + 未知结果! direct: + redirected: | + 成功重定向到上游库 `%{upstream}`! + + redirect_failed: | + 重定向失败:%{err}! + directed_and_stained: | 成功定向到上游库 `%{upstream}`! 工作区已被 **染色**,现可开始工作! @@ -437,6 +471,19 @@ jv: 当前工作区已被染色,无法定向其他不同标识的上游库 请先使用 jv unstain 祛色 + same_upstream: | + 当前上游和给出的一致,无需重定向 + update: success: | 已同步至最新信息! + + sheet: + make: + success: | + 成功创建表 `%{name}`! + 上游信息已变更,请使用 `jv update` 同步至最新信息 + sheet_already_exists: | + 表 `%{name}` 已存在! + sheet_creation_failed: | + 表创建失败:`%{err}` diff --git a/src/bin/jv.rs b/src/bin/jv.rs index bd8215a..b7eb105 100644 --- a/src/bin/jv.rs +++ b/src/bin/jv.rs @@ -1,17 +1,24 @@ use std::{env::current_dir, net::SocketAddr, path::PathBuf, process::exit}; use just_enough_vcs::{ - system::action_system::action::ActionContext, - utils::{cfg_file::config::ConfigFile, tcp_connection::instance::ConnectionInstance}, + system::action_system::{action::ActionContext, action_pool::ActionPool}, + utils::{ + cfg_file::config::ConfigFile, + string_proc::{self, snake_case}, + tcp_connection::instance::ConnectionInstance, + }, vcs::{ - actions::local_actions::{ - SetUpstreamVaultActionResult, UpdateToLatestInfoResult, - proc_update_to_latest_info_action, + actions::{ + local_actions::{ + SetUpstreamVaultActionResult, UpdateToLatestInfoResult, + proc_update_to_latest_info_action, + }, + sheet_actions::{MakeSheetActionResult, proc_make_sheet_action}, }, constants::PORT, current::current_local_path, data::{ - local::{LocalWorkspace, config::LocalConfig}, + local::{LocalWorkspace, config::LocalConfig, latest_info::LatestInfo}, member::Member, user::UserDirectory, }, @@ -67,7 +74,7 @@ enum JustEnoughVcsWorkspaceCommand { // Sheet management /// Manage sheets in the workspace - #[command(subcommand)] + #[command(subcommand, alias = "sh")] Sheet(SheetManage), // File management @@ -98,6 +105,7 @@ enum JustEnoughVcsWorkspaceCommand { Import(ImportFileArgs), /// Sync information from upstream vault + #[command(alias = "u")] Update(UpdateArgs), // Connection management @@ -110,6 +118,16 @@ enum JustEnoughVcsWorkspaceCommand { // Other /// Query built-in documentation Docs(DocsArgs), + + // Lazy commands + /// Try exit current sheet + Exit, + + /// Try exit current sheet and use another sheet + Use(UseArgs), + + /// List all sheets + Sheets, } #[derive(Subcommand, Debug)] @@ -143,6 +161,67 @@ enum SheetManage { /// Show help information #[command(alias = "--help", alias = "-h")] Help, + + /// List all sheets + #[command(alias = "ls")] + List(SheetListArgs), + + /// Use a sheet + Use(SheetUseArgs), + + /// Exit current sheet + Exit(SheetExitArgs), + + /// Create a new sheet + #[command(alias = "mk")] + Make(SheetMakeArgs), + + /// Drop current sheet + Drop(SheetDropArgs), +} + +#[derive(Parser, Debug)] +struct SheetListArgs { + /// Show help information + #[arg(short, long)] + help: bool, +} + +#[derive(Parser, Debug)] +struct SheetUseArgs { + /// Show help information + #[arg(short, long)] + help: bool, + + /// Sheet name + sheet_name: String, +} + +#[derive(Parser, Debug)] +struct SheetExitArgs { + /// Show help information + #[arg(short, long)] + help: bool, +} + +#[derive(Parser, Debug)] +struct SheetMakeArgs { + /// Show help information + #[arg(short, long)] + help: bool, + + /// Sheet name + sheet_name: String, +} + +#[derive(Parser, Debug)] +struct SheetDropArgs { + /// Show help information + #[arg(short, long)] + help: bool, + + /// Sheet name + sheet_name: String, } #[derive(Parser, Debug)] @@ -308,6 +387,11 @@ struct DocsArgs { help: bool, } +#[derive(Parser, Debug)] +struct UseArgs { + sheet_name: String, +} + #[tokio::main] async fn main() { // Init i18n @@ -403,6 +487,11 @@ async fn main() { println!("{}", md(t!("jv.sheet"))); return; } + SheetManage::List(sheet_list_args) => jv_sheet_list(sheet_list_args).await, + SheetManage::Use(sheet_use_args) => jv_sheet_use(sheet_use_args).await, + SheetManage::Exit(sheet_exit_args) => jv_sheet_exit(sheet_exit_args).await, + SheetManage::Make(sheet_make_args) => jv_sheet_make(sheet_make_args).await, + SheetManage::Drop(sheet_drop_args) => jv_sheet_drop(sheet_drop_args).await, }, JustEnoughVcsWorkspaceCommand::Track(track_file_args) => { if track_file_args.help { @@ -474,6 +563,18 @@ async fn main() { } jv_docs(docs_args).await; } + JustEnoughVcsWorkspaceCommand::Exit => { + jv_sheet_exit(SheetExitArgs { help: false }).await; + } + JustEnoughVcsWorkspaceCommand::Use(use_args) => { + jv_sheet_exit(SheetExitArgs { help: false }).await; + jv_sheet_use(SheetUseArgs { + help: false, + sheet_name: use_args.sheet_name, + }) + .await; + } + JustEnoughVcsWorkspaceCommand::Sheets => jv_sheet_list(SheetListArgs { help: false }).await, } } @@ -530,6 +631,192 @@ async fn jv_here(_args: HereArgs) { todo!() } +async fn jv_sheet_list(_args: SheetListArgs) { + let Some(_local_dir) = current_local_path() else { + eprintln!("{}", t!("jv.fail.workspace_not_found").trim()); + return; + }; + + let Ok(latest_info) = LatestInfo::read().await else { + eprintln!("{}", md(t!("jv.fail.read_cfg"))); + return; + }; + + let Ok(local_cfg) = LocalConfig::read().await else { + eprintln!("{}", md(t!("jv.fail.read_cfg"))); + return; + }; + + let mut your_sheet_counts = 0; + let mut other_sheet_counts = 0; + + // Print your sheets + { + println!("{}", md(t!("jv.success.sheet.list.your_sheet"))); + let in_use = local_cfg.sheet_in_use(); + for sheet in latest_info.my_sheets { + if let Some(in_use) = in_use + && in_use == &sheet + { + println!( + "{}", + md(t!( + "jv.success.sheet.list.your_sheet_item_use", + number = your_sheet_counts + 1, + name = sheet + )) + ); + } else { + println!( + "{}", + md(t!( + "jv.success.sheet.list.your_sheet_item", + number = your_sheet_counts + 1, + name = sheet + )) + ); + } + your_sheet_counts += 1; + } + println!(); + } + + // Print other sheets + { + println!("{}", md(t!("jv.success.sheet.list.other_sheet"))); + for sheet in latest_info.other_sheets { + if let Some(holder) = sheet.holder_name { + println!( + "{}", + md(t!( + "jv.success.sheet.list.other_sheet_item", + number = other_sheet_counts + 1, + name = sheet.sheet_name, + holder = holder + )) + ); + } else { + println!( + "{}", + md(t!( + "jv.success.sheet.list.other_sheet_item_no_holder", + number = other_sheet_counts + 1, + name = sheet.sheet_name + )) + ); + } + other_sheet_counts += 1; + } + println!(); + } + + // Print tips + { + if your_sheet_counts > 0 { + println!("{}", md(t!("jv.success.sheet.list.tip_has_sheet"))); + } else { + println!("{}", md(t!("jv.success.sheet.list.tip_no_sheet"))); + } + } +} + +async fn jv_sheet_use(args: SheetUseArgs) { + let Some(_local_dir) = current_local_path() else { + eprintln!("{}", t!("jv.fail.workspace_not_found").trim()); + return; + }; + + let Ok(mut local_cfg) = LocalConfig::read().await else { + eprintln!("{}", md(t!("jv.fail.read_cfg"))); + return; + }; + + match local_cfg.use_sheet(args.sheet_name).await { + Ok(_) => { + let Ok(_) = LocalConfig::write(&local_cfg).await else { + eprintln!("{}", t!("jv.fail.write_cfg").trim()); + return; + }; + } + Err(e) => { + handle_err(e.into()); + } + } +} + +async fn jv_sheet_exit(_args: SheetExitArgs) { + let Some(_local_dir) = current_local_path() else { + eprintln!("{}", t!("jv.fail.workspace_not_found").trim()); + return; + }; + + let Ok(mut local_cfg) = LocalConfig::read().await else { + eprintln!("{}", md(t!("jv.fail.read_cfg"))); + return; + }; + + match local_cfg.exit_sheet().await { + Ok(_) => { + let Ok(_) = LocalConfig::write(&local_cfg).await else { + eprintln!("{}", t!("jv.fail.write_cfg").trim()); + return; + }; + } + Err(e) => { + handle_err(e.into()); + } + } +} + +async fn jv_sheet_make(args: SheetMakeArgs) { + let sheet_name = snake_case!(args.sheet_name); + + let local_config = match precheck().await { + Some(config) => config, + None => return, + }; + + let (pool, ctx) = match build_pool_and_ctx(&local_config).await { + Some(result) => result, + None => return, + }; + + match proc_make_sheet_action(&pool, ctx, sheet_name.clone()).await { + Ok(r) => match r { + MakeSheetActionResult::Success => { + eprintln!( + "{}", + md(t!("jv.result.sheet.make.success", name = sheet_name)) + ) + } + MakeSheetActionResult::AuthorizeFailed(e) => { + eprintln!("{}", md(t!("jv.result.common.authroize_failed", err = e))) + } + MakeSheetActionResult::SheetAlreadyExists => { + eprintln!( + "{}", + md(t!( + "jv.result.sheet.make.sheet_already_exists", + name = sheet_name + )) + ); + } + MakeSheetActionResult::SheetCreationFailed(e) => { + println!( + "{}", + md(t!("jv.result.sheet.make.sheet_creation_failed", err = e)) + ) + } + MakeSheetActionResult::Unknown => todo!(), + }, + Err(e) => handle_err(e), + } +} + +async fn jv_sheet_drop(_args: SheetDropArgs) { + todo!() +} + async fn jv_track(_args: TrackFileArgs) { todo!() } @@ -681,25 +968,16 @@ async fn jv_account_move_key(user_dir: UserDirectory, args: MoveKeyToAccountArgs } async fn jv_update(_update_file_args: UpdateArgs) { - let Ok(local_config) = LocalConfig::read().await else { - eprintln!("{}", md(t!("jv.fail.read_cfg"))); - return; + let local_config = match precheck().await { + Some(config) => config, + None => return, }; - if !local_config.stained() { - eprintln!("{}", md(t!("jv.fail.not_stained"))); - return; - } - - let pool = client_registry::client_action_pool(); - let upstream = local_config.upstream_addr(); - - let Some(instance) = connect(upstream).await else { - return; + let (pool, ctx) = match build_pool_and_ctx(&local_config).await { + Some(result) => result, + None => return, }; - let ctx = ActionContext::local().insert_instance(instance); - match proc_update_to_latest_info_action(&pool, ctx, ()).await { Err(e) => handle_err(e), Ok(result) => match result { @@ -707,10 +985,7 @@ async fn jv_update(_update_file_args: UpdateArgs) { println!("{}", md(t!("jv.result.update.success"))); } UpdateToLatestInfoResult::AuthorizeFailed(e) => { - println!( - "{}", - md(t!("jv.result.direct.directed_and_stained", err = e)) - ) + println!("{}", md(t!("jv.result.common.authroize_failed", err = e))) } }, } @@ -760,15 +1035,25 @@ async fn jv_direct(args: DirectArgs) { )) ) } + SetUpstreamVaultActionResult::Redirected => { + println!( + "{}", + md(t!("jv.result.direct.redirected", upstream = upstream)) + ) + } SetUpstreamVaultActionResult::AlreadyStained => { eprintln!("{}", md(t!("jv.result.direct.already_stained"))) } SetUpstreamVaultActionResult::AuthorizeFailed(e) => { - println!( - "{}", - md(t!("jv.result.direct.directed_and_stained", err = e)) - ) + println!("{}", md(t!("jv.result.common.authroize_failed", err = e))) } + SetUpstreamVaultActionResult::RedirectFailed(e) => { + println!("{}", md(t!("jv.result.direct.redirect_failed", err = e))) + } + SetUpstreamVaultActionResult::SameUpstream => { + println!("{}", md(t!("jv.result.direct.same_upstream"))) + } + _ => {} }, }; } @@ -843,3 +1128,31 @@ async fn connect(upstream: SocketAddr) -> Option { Some(ConnectionInstance::from(stream)) } + +// Check if the workspace is stained and has a valid configuration +// Returns LocalConfig if valid, None otherwise +async fn precheck() -> Option { + let Ok(local_config) = LocalConfig::read().await else { + eprintln!("{}", md(t!("jv.fail.read_cfg"))); + return None; + }; + + if !local_config.stained() { + eprintln!("{}", md(t!("jv.fail.not_stained"))); + return None; + } + + Some(local_config) +} + +// Build action pool and context for upstream communication +// Returns Some((ActionPool, ActionContext)) if successful, None otherwise +async fn build_pool_and_ctx(local_config: &LocalConfig) -> Option<(ActionPool, ActionContext)> { + let pool = client_registry::client_action_pool(); + let upstream = local_config.upstream_addr(); + + let instance = connect(upstream).await?; + + let ctx = ActionContext::local().insert_instance(instance); + Some((pool, ctx)) +} -- cgit