Extract the argument text up to the next top-level comma or closing paren, respecting nesting of `()`, `[]`, and `{}`.
(s: &str)
| 440 | /// Extract the argument text up to the next top-level comma or closing |
| 441 | /// paren, respecting nesting of `()`, `[]`, and `{}`. |
| 442 | fn extract_argument_text(s: &str) -> &str { |
| 443 | let mut depth_paren = 0i32; |
| 444 | let mut depth_bracket = 0i32; |
| 445 | let mut depth_brace = 0i32; |
| 446 | let mut in_single_quote = false; |
| 447 | let mut in_double_quote = false; |
| 448 | let mut prev_was_escape = false; |
| 449 | |
| 450 | for (i, ch) in s.char_indices() { |
| 451 | if prev_was_escape { |
| 452 | prev_was_escape = false; |
| 453 | continue; |
| 454 | } |
| 455 | if ch == '\\' && (in_single_quote || in_double_quote) { |
| 456 | prev_was_escape = true; |
| 457 | continue; |
| 458 | } |
| 459 | if in_single_quote { |
| 460 | if ch == '\'' { |
| 461 | in_single_quote = false; |
| 462 | } |
| 463 | continue; |
| 464 | } |
| 465 | if in_double_quote { |
| 466 | if ch == '"' { |
| 467 | in_double_quote = false; |
| 468 | } |
| 469 | continue; |
| 470 | } |
| 471 | match ch { |
| 472 | '\'' => in_single_quote = true, |
| 473 | '"' => in_double_quote = true, |
| 474 | '(' => depth_paren += 1, |
| 475 | ')' => { |
| 476 | if depth_paren == 0 { |
| 477 | return &s[..i]; |
| 478 | } |
| 479 | depth_paren -= 1; |
| 480 | } |
| 481 | '[' => depth_bracket += 1, |
| 482 | ']' => depth_bracket = (depth_bracket - 1).max(0), |
| 483 | '{' => depth_brace += 1, |
| 484 | '}' => depth_brace = (depth_brace - 1).max(0), |
| 485 | ',' if depth_paren == 0 && depth_bracket == 0 && depth_brace == 0 => { |
| 486 | return &s[..i]; |
| 487 | } |
| 488 | _ => {} |
| 489 | } |
| 490 | } |
| 491 | s |
| 492 | } |
| 493 | |
| 494 | /// Extract the trailing identifier from a member-access expression. |
| 495 | /// For `$this->foo->bar`, returns `"bar"`. |
no outgoing calls
no test coverage detected