Given a multi-line string, split it into a sequence of lines after stripping a common indentation. This is useful for strings defined with doc strings.
(s: &str)
| 263 | /// stripping a common indentation. This is useful for strings defined with |
| 264 | /// doc strings. |
| 265 | fn parse_multiline(s: &str) -> Vec<String> { |
| 266 | // Convert tabs into spaces. |
| 267 | let expanded_tab = format!("{:-1$}", " ", SHIFTWIDTH); |
| 268 | let lines: Vec<String> = s.lines().map(|l| l.replace('\t', &expanded_tab)).collect(); |
| 269 | |
| 270 | // Determine minimum indentation, ignoring the first line and empty lines. |
| 271 | let indent = lines |
| 272 | .iter() |
| 273 | .skip(1) |
| 274 | .filter(|l| !l.trim().is_empty()) |
| 275 | .map(|l| l.len() - l.trim_start().len()) |
| 276 | .min(); |
| 277 | |
| 278 | // Strip off leading blank lines. |
| 279 | let mut lines_iter = lines.iter().skip_while(|l| l.is_empty()); |
| 280 | let mut trimmed = Vec::with_capacity(lines.len()); |
| 281 | |
| 282 | // Remove indentation (first line is special) |
| 283 | if let Some(s) = lines_iter.next().map(|l| l.trim()).map(|l| l.to_string()) { |
| 284 | trimmed.push(s); |
| 285 | } |
| 286 | |
| 287 | // Remove trailing whitespace from other lines. |
| 288 | let mut other_lines = if let Some(indent) = indent { |
| 289 | // Note that empty lines may have fewer than `indent` chars. |
| 290 | lines_iter |
| 291 | .map(|l| &l[cmp::min(indent, l.len())..]) |
| 292 | .map(|l| l.trim_end()) |
| 293 | .map(|l| l.to_string()) |
| 294 | .collect::<Vec<_>>() |
| 295 | } else { |
| 296 | lines_iter |
| 297 | .map(|l| l.trim_end()) |
| 298 | .map(|l| l.to_string()) |
| 299 | .collect::<Vec<_>>() |
| 300 | }; |
| 301 | |
| 302 | trimmed.append(&mut other_lines); |
| 303 | |
| 304 | // Strip off trailing blank lines. |
| 305 | while let Some(s) = trimmed.pop() { |
| 306 | if s.is_empty() { |
| 307 | continue; |
| 308 | } else { |
| 309 | trimmed.push(s); |
| 310 | break; |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | trimmed |
| 315 | } |
| 316 | |
| 317 | /// Match formatting class. |
| 318 | /// |