424 lines
12 KiB
Rust
424 lines
12 KiB
Rust
use crate::infrastructure::markdown_parser::{
|
||
MarkdownParser, MarkdownParserConfig, MarkdownParseResult,
|
||
OutlineItem, LinkInfo, ValidationResult, MarkdownNode, Range, Position
|
||
};
|
||
use anyhow::Result;
|
||
use serde::{Deserialize, Serialize};
|
||
use std::sync::Mutex;
|
||
use tauri::{command, State};
|
||
use tracing::{error, info};
|
||
|
||
/// Markdown解析器状态
|
||
pub struct MarkdownParserState {
|
||
parser: Mutex<Option<MarkdownParser>>,
|
||
}
|
||
|
||
impl MarkdownParserState {
|
||
pub fn new() -> Self {
|
||
Self {
|
||
parser: Mutex::new(None),
|
||
}
|
||
}
|
||
|
||
/// 获取或创建解析器实例
|
||
pub fn get_or_create_parser(&self, config: Option<MarkdownParserConfig>) -> Result<()> {
|
||
let mut parser_guard = self.parser.lock().unwrap();
|
||
if parser_guard.is_none() {
|
||
let parser = MarkdownParser::new(config)?;
|
||
*parser_guard = Some(parser);
|
||
}
|
||
Ok(())
|
||
}
|
||
|
||
/// 执行解析操作
|
||
pub fn with_parser<F, R>(&self, f: F) -> Result<R>
|
||
where
|
||
F: FnOnce(&mut MarkdownParser) -> Result<R>,
|
||
{
|
||
let mut parser_guard = self.parser.lock().unwrap();
|
||
if let Some(ref mut parser) = *parser_guard {
|
||
f(parser)
|
||
} else {
|
||
Err(anyhow::anyhow!("Parser not initialized"))
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 解析Markdown请求
|
||
#[derive(Debug, Deserialize)]
|
||
pub struct ParseMarkdownRequest {
|
||
/// 要解析的Markdown文本
|
||
pub text: String,
|
||
/// 解析器配置
|
||
pub config: Option<MarkdownParserConfigDto>,
|
||
}
|
||
|
||
/// 解析器配置DTO
|
||
#[derive(Debug, Deserialize)]
|
||
pub struct MarkdownParserConfigDto {
|
||
/// 是否保留空白节点
|
||
pub preserve_whitespace: Option<bool>,
|
||
/// 是否解析内联HTML
|
||
pub parse_inline_html: Option<bool>,
|
||
/// 最大解析深度
|
||
pub max_depth: Option<usize>,
|
||
/// 超时时间(毫秒)
|
||
pub timeout_ms: Option<u64>,
|
||
}
|
||
|
||
impl From<MarkdownParserConfigDto> for MarkdownParserConfig {
|
||
fn from(dto: MarkdownParserConfigDto) -> Self {
|
||
let default = MarkdownParserConfig::default();
|
||
Self {
|
||
preserve_whitespace: dto.preserve_whitespace.unwrap_or(default.preserve_whitespace),
|
||
parse_inline_html: dto.parse_inline_html.unwrap_or(default.parse_inline_html),
|
||
max_depth: dto.max_depth.unwrap_or(default.max_depth),
|
||
timeout_ms: dto.timeout_ms.unwrap_or(default.timeout_ms),
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 解析Markdown响应
|
||
#[derive(Debug, Serialize)]
|
||
pub struct ParseMarkdownResponse {
|
||
/// 是否成功
|
||
pub success: bool,
|
||
/// 解析结果
|
||
pub result: Option<MarkdownParseResult>,
|
||
/// 错误信息
|
||
pub error: Option<String>,
|
||
}
|
||
|
||
/// 查询节点请求
|
||
#[derive(Debug, Deserialize)]
|
||
pub struct QueryNodesRequest {
|
||
/// Markdown文本
|
||
pub text: String,
|
||
/// 查询名称
|
||
pub query_name: String,
|
||
}
|
||
|
||
/// 查询节点响应
|
||
#[derive(Debug, Serialize)]
|
||
pub struct QueryNodesResponse {
|
||
/// 是否成功
|
||
pub success: bool,
|
||
/// 查询结果
|
||
pub nodes: Option<Vec<MarkdownNode>>,
|
||
/// 错误信息
|
||
pub error: Option<String>,
|
||
}
|
||
|
||
/// 位置查询请求
|
||
#[derive(Debug, Deserialize)]
|
||
pub struct FindNodeAtPositionRequest {
|
||
/// Markdown文本
|
||
pub text: String,
|
||
/// 行号(从0开始)
|
||
pub line: usize,
|
||
/// 列号(从0开始)
|
||
pub column: usize,
|
||
}
|
||
|
||
/// 位置查询响应
|
||
#[derive(Debug, Serialize)]
|
||
pub struct FindNodeAtPositionResponse {
|
||
/// 是否成功
|
||
pub success: bool,
|
||
/// 找到的节点
|
||
pub node: Option<MarkdownNode>,
|
||
/// 错误信息
|
||
pub error: Option<String>,
|
||
}
|
||
|
||
/// 大纲提取请求
|
||
#[derive(Debug, Deserialize)]
|
||
pub struct ExtractOutlineRequest {
|
||
/// Markdown文本
|
||
pub text: String,
|
||
}
|
||
|
||
/// 大纲提取响应
|
||
#[derive(Debug, Serialize)]
|
||
pub struct ExtractOutlineResponse {
|
||
/// 是否成功
|
||
pub success: bool,
|
||
/// 大纲项目
|
||
pub outline: Option<Vec<OutlineItem>>,
|
||
/// 错误信息
|
||
pub error: Option<String>,
|
||
}
|
||
|
||
/// 链接提取请求
|
||
#[derive(Debug, Deserialize)]
|
||
pub struct ExtractLinksRequest {
|
||
/// Markdown文本
|
||
pub text: String,
|
||
}
|
||
|
||
/// 链接提取响应
|
||
#[derive(Debug, Serialize)]
|
||
pub struct ExtractLinksResponse {
|
||
/// 是否成功
|
||
pub success: bool,
|
||
/// 链接信息
|
||
pub links: Option<Vec<LinkInfo>>,
|
||
/// 错误信息
|
||
pub error: Option<String>,
|
||
}
|
||
|
||
/// 验证请求
|
||
#[derive(Debug, Deserialize)]
|
||
pub struct ValidateMarkdownRequest {
|
||
/// Markdown文本
|
||
pub text: String,
|
||
}
|
||
|
||
/// 验证响应
|
||
#[derive(Debug, Serialize)]
|
||
pub struct ValidateMarkdownResponse {
|
||
/// 是否成功
|
||
pub success: bool,
|
||
/// 验证结果
|
||
pub validation: Option<ValidationResult>,
|
||
/// 错误信息
|
||
pub error: Option<String>,
|
||
}
|
||
|
||
/// 解析Markdown文档
|
||
#[command]
|
||
pub async fn parse_markdown(
|
||
request: ParseMarkdownRequest,
|
||
state: State<'_, MarkdownParserState>,
|
||
) -> Result<ParseMarkdownResponse, String> {
|
||
info!("Received Markdown parse request, text length: {}", request.text.len());
|
||
|
||
// 转换配置
|
||
let parser_config = request.config.map(|c| c.into());
|
||
|
||
// 确保解析器已初始化
|
||
if let Err(e) = state.get_or_create_parser(parser_config) {
|
||
error!("Failed to initialize Markdown parser: {}", e);
|
||
return Ok(ParseMarkdownResponse {
|
||
success: false,
|
||
result: None,
|
||
error: Some(format!("Parser initialization failed: {}", e)),
|
||
});
|
||
}
|
||
|
||
// 执行解析
|
||
match state.with_parser(|parser| parser.parse(&request.text)) {
|
||
Ok(result) => {
|
||
info!("Markdown parsing completed successfully");
|
||
Ok(ParseMarkdownResponse {
|
||
success: true,
|
||
result: Some(result),
|
||
error: None,
|
||
})
|
||
}
|
||
Err(e) => {
|
||
error!("Markdown parsing failed: {}", e);
|
||
Ok(ParseMarkdownResponse {
|
||
success: false,
|
||
result: None,
|
||
error: Some(e.to_string()),
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 查询特定类型的节点
|
||
#[command]
|
||
pub async fn query_markdown_nodes(
|
||
request: QueryNodesRequest,
|
||
state: State<'_, MarkdownParserState>,
|
||
) -> Result<QueryNodesResponse, String> {
|
||
info!("Received query nodes request: {}", request.query_name);
|
||
|
||
// 确保解析器已初始化
|
||
if let Err(e) = state.get_or_create_parser(None) {
|
||
error!("Failed to initialize Markdown parser: {}", e);
|
||
return Ok(QueryNodesResponse {
|
||
success: false,
|
||
nodes: None,
|
||
error: Some(format!("Parser initialization failed: {}", e)),
|
||
});
|
||
}
|
||
|
||
// 执行查询
|
||
match state.with_parser(|parser| parser.query_nodes(&request.text, &request.query_name)) {
|
||
Ok(nodes) => {
|
||
info!("Query completed successfully, found {} nodes", nodes.len());
|
||
Ok(QueryNodesResponse {
|
||
success: true,
|
||
nodes: Some(nodes),
|
||
error: None,
|
||
})
|
||
}
|
||
Err(e) => {
|
||
error!("Query failed: {}", e);
|
||
Ok(QueryNodesResponse {
|
||
success: false,
|
||
nodes: None,
|
||
error: Some(e.to_string()),
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 根据位置查找节点
|
||
#[command]
|
||
pub async fn find_markdown_node_at_position(
|
||
request: FindNodeAtPositionRequest,
|
||
state: State<'_, MarkdownParserState>,
|
||
) -> Result<FindNodeAtPositionResponse, String> {
|
||
info!("Received find node at position request: {}:{}", request.line, request.column);
|
||
|
||
// 确保解析器已初始化
|
||
if let Err(e) = state.get_or_create_parser(None) {
|
||
error!("Failed to initialize Markdown parser: {}", e);
|
||
return Ok(FindNodeAtPositionResponse {
|
||
success: false,
|
||
node: None,
|
||
error: Some(format!("Parser initialization failed: {}", e)),
|
||
});
|
||
}
|
||
|
||
// 执行查找
|
||
match state.with_parser(|parser| parser.find_node_at_position(&request.text, request.line, request.column)) {
|
||
Ok(node) => {
|
||
info!("Find node at position completed successfully");
|
||
Ok(FindNodeAtPositionResponse {
|
||
success: true,
|
||
node,
|
||
error: None,
|
||
})
|
||
}
|
||
Err(e) => {
|
||
error!("Find node at position failed: {}", e);
|
||
Ok(FindNodeAtPositionResponse {
|
||
success: false,
|
||
node: None,
|
||
error: Some(e.to_string()),
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 提取文档大纲
|
||
#[command]
|
||
pub async fn extract_markdown_outline(
|
||
request: ExtractOutlineRequest,
|
||
state: State<'_, MarkdownParserState>,
|
||
) -> Result<ExtractOutlineResponse, String> {
|
||
info!("Received extract outline request");
|
||
|
||
// 确保解析器已初始化
|
||
if let Err(e) = state.get_or_create_parser(None) {
|
||
error!("Failed to initialize Markdown parser: {}", e);
|
||
return Ok(ExtractOutlineResponse {
|
||
success: false,
|
||
outline: None,
|
||
error: Some(format!("Parser initialization failed: {}", e)),
|
||
});
|
||
}
|
||
|
||
// 执行大纲提取
|
||
match state.with_parser(|parser| parser.extract_outline(&request.text)) {
|
||
Ok(outline) => {
|
||
info!("Extract outline completed successfully, found {} items", outline.len());
|
||
Ok(ExtractOutlineResponse {
|
||
success: true,
|
||
outline: Some(outline),
|
||
error: None,
|
||
})
|
||
}
|
||
Err(e) => {
|
||
error!("Extract outline failed: {}", e);
|
||
Ok(ExtractOutlineResponse {
|
||
success: false,
|
||
outline: None,
|
||
error: Some(e.to_string()),
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 提取所有链接
|
||
#[command]
|
||
pub async fn extract_markdown_links(
|
||
request: ExtractLinksRequest,
|
||
state: State<'_, MarkdownParserState>,
|
||
) -> Result<ExtractLinksResponse, String> {
|
||
info!("Received extract links request");
|
||
|
||
// 确保解析器已初始化
|
||
if let Err(e) = state.get_or_create_parser(None) {
|
||
error!("Failed to initialize Markdown parser: {}", e);
|
||
return Ok(ExtractLinksResponse {
|
||
success: false,
|
||
links: None,
|
||
error: Some(format!("Parser initialization failed: {}", e)),
|
||
});
|
||
}
|
||
|
||
// 执行链接提取
|
||
match state.with_parser(|parser| parser.extract_links(&request.text)) {
|
||
Ok(links) => {
|
||
info!("Extract links completed successfully, found {} links", links.len());
|
||
Ok(ExtractLinksResponse {
|
||
success: true,
|
||
links: Some(links),
|
||
error: None,
|
||
})
|
||
}
|
||
Err(e) => {
|
||
error!("Extract links failed: {}", e);
|
||
Ok(ExtractLinksResponse {
|
||
success: false,
|
||
links: None,
|
||
error: Some(e.to_string()),
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 验证Markdown文档结构
|
||
#[command]
|
||
pub async fn validate_markdown(
|
||
request: ValidateMarkdownRequest,
|
||
state: State<'_, MarkdownParserState>,
|
||
) -> Result<ValidateMarkdownResponse, String> {
|
||
info!("Received validate markdown request");
|
||
|
||
// 确保解析器已初始化
|
||
if let Err(e) = state.get_or_create_parser(None) {
|
||
error!("Failed to initialize Markdown parser: {}", e);
|
||
return Ok(ValidateMarkdownResponse {
|
||
success: false,
|
||
validation: None,
|
||
error: Some(format!("Parser initialization failed: {}", e)),
|
||
});
|
||
}
|
||
|
||
// 执行验证
|
||
match state.with_parser(|parser| parser.validate_structure(&request.text)) {
|
||
Ok(validation) => {
|
||
info!("Validate markdown completed successfully, found {} issues", validation.issues.len());
|
||
Ok(ValidateMarkdownResponse {
|
||
success: true,
|
||
validation: Some(validation),
|
||
error: None,
|
||
})
|
||
}
|
||
Err(e) => {
|
||
error!("Validate markdown failed: {}", e);
|
||
Ok(ValidateMarkdownResponse {
|
||
success: false,
|
||
validation: None,
|
||
error: Some(e.to_string()),
|
||
})
|
||
}
|
||
}
|
||
}
|