feat(dbx-core): 新增 CLI envelope DTO

- 添加 CLI source、error code、error 和 envelope 类型

- 导出 dbx-core::cli 模块并补充序列化单元测试

- 补齐既有测试 fixture 的 JDBC 默认字段以恢复目标测试编译
This commit is contained in:
Illuminated2020 2026-05-10 16:52:39 +08:00
parent dd113ed714
commit 10373bdf36
2 changed files with 68 additions and 0 deletions

View File

@ -0,0 +1,67 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum CliSource {
GuiRuntime,
Headless,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum CliErrorCode {
GuiRuntimeRequired,
ConnectionNotFound,
AmbiguousConnection,
SecretUnavailable,
SshTunnelFailed,
QueryClassificationFailed,
HandoffRequired,
DdlBlocked,
ProductionWriteBlocked,
UnsupportedDatabaseType,
Timeout,
InternalError,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CliError {
pub code: CliErrorCode,
pub message: String,
pub recoverable: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CliEnvelope<T> {
Success { ok: bool, source: CliSource, data: T },
Failure { ok: bool, source: CliSource, error: CliError },
}
pub fn ok<T>(source: CliSource, data: T) -> CliEnvelope<T> {
CliEnvelope::Success { ok: true, source, data }
}
pub fn fail<T>(source: CliSource, code: CliErrorCode, message: impl Into<String>, recoverable: bool) -> CliEnvelope<T> {
CliEnvelope::Failure { ok: false, source, error: CliError { code, message: message.into(), recoverable } }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serializes_success_source_as_kebab_case() {
let env = ok(CliSource::GuiRuntime, serde_json::json!({"value": 1}));
let json = serde_json::to_string(&env).unwrap();
assert!(json.contains("\"ok\":true"));
assert!(json.contains("\"source\":\"gui-runtime\""));
}
#[test]
fn serializes_error_code_as_screaming_snake_case() {
let env: CliEnvelope<()> = fail(CliSource::Headless, CliErrorCode::GuiRuntimeRequired, "runtime needed", true);
let json = serde_json::to_string(&env).unwrap();
assert!(json.contains("\"GUI_RUNTIME_REQUIRED\""));
}
}

View File

@ -1,4 +1,5 @@
pub mod ai;
pub mod cli;
pub mod connection;
pub mod connection_secrets;
pub mod db;