Lenient scan for a single `:::memory` container fence, returning its inner body if present. Unlike the closed-vocabulary [`crate::directive`] parser, this never errors on unrelated `::`/`:::` tokens in the open memory prose — only a recognized fence (a name in [`LIFTED_MEMORY_DIRECTIVES`]) is treated as structure; everything else is content. An unterminated fence falls back to the whole body (fail
(body: &str)
| 174 | /// as structure; everything else is content. An unterminated fence falls back |
| 175 | /// to the whole body (fail-open, preserving content). |
| 176 | fn extract_memory_container(body: &str) -> Option<String> { |
| 177 | let lines: Vec<&str> = body.lines().collect(); |
| 178 | let mut i = 0; |
| 179 | while i < lines.len() { |
| 180 | if let Some(name) = container_open_name(lines[i].trim_start()) { |
| 181 | if LIFTED_MEMORY_DIRECTIVES.contains(&name) { |
| 182 | let mut collected: Vec<&str> = Vec::new(); |
| 183 | i += 1; |
| 184 | while i < lines.len() { |
| 185 | if lines[i].trim() == ":::" { |
| 186 | return Some(collected.join("\n").trim().to_string()); |
| 187 | } |
| 188 | collected.push(lines[i]); |
| 189 | i += 1; |
| 190 | } |
| 191 | return None; // unterminated → fall back to whole body |
| 192 | } |
| 193 | } |
| 194 | i += 1; |
| 195 | } |
| 196 | None |
| 197 | } |
| 198 | |
| 199 | /// If `line` opens a container directive (`:::name` optionally with `{...}`), |
| 200 | /// return the directive name. A bare `:::` (a close) yields `None`. |
no test coverage detected