feat: 优化 parse_post_content 函数,支持处理包含内容数组的代码块,并添加相关单元测试以确保向后兼容性

This commit is contained in:
oudecheng 2026-05-21 17:17:44 +08:00
parent efc8af12eb
commit 3128abe3c6

View File

@ -1384,7 +1384,16 @@ fn parse_post_content(content: &str) -> String {
}
"code_block" => {
let lang = el.get("language").and_then(|l| l.as_str()).unwrap_or("");
let code_text = el.get("text").and_then(|t| t.as_str()).unwrap_or("");
let code_text = if let Some(content_arr) = el.get("content").and_then(|c| c.as_array()) {
content_arr
.iter()
.filter_map(|item| item.get("text").and_then(|t| t.as_str()))
.collect::<Vec<_>>()
.join("")
} else {
// Fallback to text field for backwards compatibility
el.get("text").and_then(|t| t.as_str()).unwrap_or("").to_string()
};
out.push(format!("\n```{}\n{}\n```\n", lang, code_text));
}
_ => {
@ -2190,7 +2199,7 @@ fn sanitize_download_file_name(file_name: &str) -> String {
mod tests {
use super::{
FeishuChannel, MsgFormat, extract_file_name_from_content_disposition,
infer_download_filename, sanitize_download_file_name,
infer_download_filename, parse_post_content, sanitize_download_file_name,
};
#[test]
@ -2279,6 +2288,42 @@ mod tests {
let file_name = extract_file_name_from_content_disposition(&headers);
assert_eq!(file_name.as_deref(), Some("archive.zip"));
}
#[test]
fn parse_post_content_handles_code_block_with_content_array() {
// Test parsing code_block with content array (standard Feishu format)
let post_json = r#"{"post":{"zh_cn":{"content":[[{"tag":"code_block","language":"python","content":[{"tag":"text","text":"def hello():"},{"tag":"text","text":" print('world')"}]}]]}}}"#;
let result = parse_post_content(post_json);
assert!(result.contains("```python"));
assert!(result.contains("def hello():"));
assert!(result.contains("print('world')"));
}
#[test]
fn parse_post_content_handles_code_block_with_fallback_text() {
// Backwards compatibility: some formats might use text field directly
let post_json = r#"{"post":{"zh_cn":{"content":[[{"tag":"code_block","language":"rust","text":"fn main() {}"}]]}}}"#;
let result = parse_post_content(post_json);
assert!(result.contains("```rust"));
assert!(result.contains("fn main() {}"));
}
#[test]
fn parse_post_content_handles_code_block_without_language() {
// Test code_block without language field
let post_json = r#"{"post":{"zh_cn":{"content":[[{"tag":"code_block","content":[{"tag":"text","text":"plain text"}]}]]}}}"#;
let result = parse_post_content(post_json);
assert!(result.contains("```"));
assert!(result.contains("plain text"));
}
#[test]
fn parse_post_content_handles_empty_code_block() {
// Test code_block with empty content
let post_json = r#"{"post":{"zh_cn":{"content":[[{"tag":"code_block","language":"go"}]]}}}"#;
let result = parse_post_content(post_json);
assert!(result.contains("```go"));
}
}
#[async_trait]