batch_mode_json/
extract_json_from_possible_backticks_block.rs1crate::ix!();
3
4pub fn extract_json_from_possible_backticks_block(content: &str) -> &str {
14 trace!("Entering extract_json_from_possible_backticks_block");
15 let trimmed_content = content.trim();
16 debug!("Trimmed content: '{}'", trimmed_content);
17
18 if trimmed_content.starts_with("```json") {
19 debug!("Detected start marker '```json'");
20 let json_start = 7; let remaining_content = &trimmed_content[json_start..];
22 debug!("Remaining after start marker: '{}'", remaining_content);
23
24 if let Some(end_marker_pos) = remaining_content.rfind("```") {
26 debug!("Detected end marker at position: {}", end_marker_pos);
27 let json_content = &remaining_content[..end_marker_pos].trim();
28 debug!("Extracted potential JSON content: '{}'", json_content);
29
30 if json_content.is_empty() {
31 debug!("JSON content is empty after trimming");
32 return "";
33 }
34
35 let final_content = json_content
36 .trim_start_matches('\n')
37 .trim_end_matches('\n')
38 .trim();
39 trace!("Final extracted JSON content with markers: '{}'", final_content);
40 return final_content;
41 }
42
43 warn!("No end marker found. Returning everything after '```json'.");
45 let final_content = remaining_content
46 .trim_start_matches('\n')
47 .trim_end_matches('\n')
48 .trim();
49 trace!("Final extracted JSON content without closing marker: '{}'", final_content);
50 return final_content;
51 }
52
53 trace!("No JSON block found; returning trimmed content: '{}'", trimmed_content);
55 trimmed_content
56}
57
58#[cfg(test)]
59mod extract_json_from_possible_backticks_block_tests {
60 use super::*;
61
62 #[traced_test]
63 fn test_extract_json_with_markers() {
64 let content = "```json\n{\"key\": \"value\"}\n```";
65 let result = extract_json_from_possible_backticks_block(content);
66 pretty_assert_eq!(result, "{\"key\": \"value\"}");
67 }
68
69 #[traced_test]
70 fn test_extract_json_with_whitespace_and_markers() {
71 let content = " \n```json\n{\"key\": \"value\"}\n```\n ";
72 let result = extract_json_from_possible_backticks_block(content);
73 pretty_assert_eq!(result, "{\"key\": \"value\"}");
74 }
75
76 #[traced_test]
77 fn test_extract_json_no_markers() {
78 let content = " {\"key\": \"value\"} ";
79 let result = extract_json_from_possible_backticks_block(content);
80 pretty_assert_eq!(result, "{\"key\": \"value\"}");
81 }
82
83 #[traced_test]
84 fn test_extract_json_incomplete_markers() {
85 let content = "```json{\"key\": \"value\"}";
86 let result = extract_json_from_possible_backticks_block(content);
87 pretty_assert_eq!(result, "{\"key\": \"value\"}");
88 }
89
90 #[traced_test]
91 fn test_extract_json_trailing_newline() {
92 let content = "```json\n{\"key\": \"value\"}\n\n```";
93 let result = extract_json_from_possible_backticks_block(content);
94 pretty_assert_eq!(result, "{\"key\": \"value\"}");
95 }
96
97 #[traced_test]
98 fn test_extract_json_empty_string() {
99 let content = " ";
100 let result = extract_json_from_possible_backticks_block(content);
101 pretty_assert_eq!(result, "");
102 }
103
104 #[traced_test]
105 fn test_extract_json_no_json_after_marker() {
106 let content = "```json```";
107 let result = extract_json_from_possible_backticks_block(content);
108 pretty_assert_eq!(result, "");
109 }
110
111 #[traced_test]
112 fn test_extract_json_with_crlf_line_endings() {
113 let content = "```json\r\n{\"key\": \"value\"}\r\n```";
115 let result = extract_json_from_possible_backticks_block(content);
116 pretty_assert_eq!(result, "{\"key\": \"value\"}");
117 }
118
119 #[traced_test]
120 fn test_extract_json_whitespace_after_marker() {
121 let content = "```json \n{\"key\": \"value\"}\n```";
122 let result = extract_json_from_possible_backticks_block(content);
123 pretty_assert_eq!(result, "{\"key\": \"value\"}");
124 }
125
126 #[traced_test]
127 fn test_extract_json_random_text_instead_of_json() {
128 let content = "```json\nsome random text\n```";
129 let result = extract_json_from_possible_backticks_block(content);
130 pretty_assert_eq!(result, "some random text");
131 }
132}