batch_mode_json/
extract_json_from_possible_backticks_block.rs

1// ---------------- [ File: src/extract_json_from_possible_backticks_block.rs ]
2crate::ix!();
3
4/// Extracts JSON from a content string by removing surrounding ```json\n and \n``` markers if present,
5/// and trims any leading or trailing whitespace from the input.
6///
7/// # Arguments
8/// * `content` - The content string to process.
9///
10/// # Returns
11/// * `&str` - The processed content string with markers and extra whitespace removed,
12///   or the original trimmed content if markers are absent.
13pub fn extract_json_from_possible_backticks_block(content: &str) -> &str {
14    let trimmed_content = content.trim();
15    if trimmed_content.starts_with("```json") {
16        let json_start = 7; // Skip past "```json"
17        let remaining_content = &trimmed_content[json_start..];
18
19        // Try to find the end marker
20        if let Some(end_marker_pos) = remaining_content.rfind("```") {
21            let json_content = &remaining_content[..end_marker_pos].trim();
22            if json_content.is_empty() {
23                return "";
24            }
25            return json_content
26                .trim_start_matches('\n')
27                .trim_end_matches('\n')
28                .trim();
29        }
30
31        // No closing backticks, treat everything after "```json" as content
32        return remaining_content
33            .trim_start_matches('\n')
34            .trim_end_matches('\n')
35            .trim();
36    }
37
38    // Not a JSON block, return the entire trimmed content
39    trimmed_content
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn test_extract_json_with_markers() {
48        let content = "```json\n{\"key\": \"value\"}\n```";
49        let result = extract_json_from_possible_backticks_block(content);
50        assert_eq!(result, "{\"key\": \"value\"}");
51    }
52
53    #[test]
54    fn test_extract_json_with_whitespace_and_markers() {
55        let content = "   \n```json\n{\"key\": \"value\"}\n```\n   ";
56        let result = extract_json_from_possible_backticks_block(content);
57        assert_eq!(result, "{\"key\": \"value\"}");
58    }
59
60    #[test]
61    fn test_extract_json_no_markers() {
62        let content = "   {\"key\": \"value\"}   ";
63        let result = extract_json_from_possible_backticks_block(content);
64        assert_eq!(result, "{\"key\": \"value\"}");
65    }
66
67    #[test]
68    fn test_extract_json_incomplete_markers() {
69        let content = "```json{\"key\": \"value\"}";
70        let result = extract_json_from_possible_backticks_block(content);
71        assert_eq!(result, "{\"key\": \"value\"}"); // Should gracefully handle missing end marker
72    }
73
74    #[test]
75    fn test_extract_json_trailing_newline() {
76        let content = "```json\n{\"key\": \"value\"}\n\n```";
77        let result = extract_json_from_possible_backticks_block(content);
78        assert_eq!(result, "{\"key\": \"value\"}");
79    }
80
81    #[test]
82    fn test_extract_json_empty_string() {
83        let content = "   ";
84        let result = extract_json_from_possible_backticks_block(content);
85        assert_eq!(result, ""); // Empty input results in empty output
86    }
87
88    #[test]
89    fn test_extract_json_no_json_after_marker() {
90        let content = "```json```";
91        let result = extract_json_from_possible_backticks_block(content);
92        assert_eq!(result, ""); // Correctly returns empty for no content
93    }
94}