配置: - rustfmt.toml: 固化 max_width=100 / 4 空格缩进,cargo fmt 全量格式化 - Cargo.toml: 配置 [lints.rust] 与 [lints.clippy] 渐进式规则 - .github/workflows/ci.yml: Rust(fmt+clippy+test) + 前端(eslint+tsc+test) 双平台 CI - Makefile: 新增 check/fmt/fix 目标,clippy 对齐 --all-targets --all-features - web: eslint flat config + prettier 配置 + package.json 脚本与依赖 - src/main.rs: loop→while 修复 clippy::never_loop 对抗性审查发现并修复: - eslint 缺 caughtErrorsIgnorePattern 导致 catch(_) 误报为 error - 前端 lint 未接入 CI,现已补上 Lint 步骤 - Makefile 与 CI 的 clippy flags 不一致,已对齐
86 lines
2.6 KiB
Rust
86 lines
2.6 KiB
Rust
use crate::command::Command;
|
||
use crate::command::context::AdapterContext;
|
||
use crate::command::response::{CommandError, CommandResponse};
|
||
|
||
/// 输入适配器:将渠道特定输入转换为 Command
|
||
///
|
||
/// 不同渠道(CLI、WebSocket、HTTP 等)实现此 trait
|
||
/// 将各自的输入格式统一转换为 Command
|
||
pub trait InputAdapter: Send + Sync {
|
||
/// 尝试将输入解析为 Command
|
||
///
|
||
/// # Returns
|
||
/// - `Ok(Some(Command))`:成功解析为命令
|
||
/// - `Ok(None)`:不是命令(如普通聊天消息)
|
||
/// - `Err(CommandError)`:解析错误(如缺少参数)
|
||
fn try_parse(&self, input: &str, ctx: AdapterContext) -> Result<Option<Command>, AdapterError>;
|
||
}
|
||
|
||
/// 输出适配器:将 CommandResponse 转换为渠道特定输出
|
||
///
|
||
/// 不同渠道(CLI、WebSocket、HTTP 等)实现此 trait
|
||
/// 将统一的 CommandResponse 转换为自己的输出格式
|
||
pub trait OutputAdapter: Send + Sync {
|
||
/// 输出类型
|
||
type Output;
|
||
|
||
/// 将 CommandResponse 转换为渠道特定输出
|
||
fn adapt(&self, response: CommandResponse) -> Self::Output;
|
||
}
|
||
|
||
/// 适配器错误
|
||
#[derive(Debug, Clone)]
|
||
pub enum AdapterError {
|
||
/// 缺少参数
|
||
MissingArgument { expected: String },
|
||
/// 解析错误
|
||
ParseError { message: String },
|
||
/// 不支持的命令
|
||
UnsupportedCommand { command: String },
|
||
}
|
||
|
||
impl AdapterError {
|
||
/// 创建缺少参数错误
|
||
pub fn missing_argument(expected: impl Into<String>) -> Self {
|
||
Self::MissingArgument {
|
||
expected: expected.into(),
|
||
}
|
||
}
|
||
|
||
/// 创建解析错误
|
||
pub fn parse_error(message: impl Into<String>) -> Self {
|
||
Self::ParseError {
|
||
message: message.into(),
|
||
}
|
||
}
|
||
|
||
/// 创建不支持命令错误
|
||
pub fn unsupported_command(command: impl Into<String>) -> Self {
|
||
Self::UnsupportedCommand {
|
||
command: command.into(),
|
||
}
|
||
}
|
||
}
|
||
|
||
impl std::fmt::Display for AdapterError {
|
||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||
match self {
|
||
AdapterError::MissingArgument { expected } => {
|
||
write!(f, "Missing argument: expected {}", expected)
|
||
}
|
||
AdapterError::ParseError { message } => write!(f, "Parse error: {}", message),
|
||
AdapterError::UnsupportedCommand { command } => {
|
||
write!(f, "Unsupported command: {}", command)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
impl std::error::Error for AdapterError {}
|
||
|
||
impl From<AdapterError> for CommandError {
|
||
fn from(err: AdapterError) -> Self {
|
||
CommandError::new("ADAPTER_ERROR", err.to_string())
|
||
}
|
||
}
|