(line: &str)
| 813 | } |
| 814 | |
| 815 | fn tokenize_step(line: &str) -> Result<Vec<String>, crate::error::AppError> { |
| 816 | enum State { |
| 817 | Normal, |
| 818 | Single, |
| 819 | Double, |
| 820 | } |
| 821 | let mut tokens = Vec::new(); |
| 822 | let mut current = String::new(); |
| 823 | let mut state = State::Normal; |
| 824 | let mut escaping = false; |
| 825 | let mut saw_boundary = false; |
| 826 | for character in line.chars() { |
| 827 | match state { |
| 828 | State::Normal => { |
| 829 | if escaping { |
| 830 | current.push(character); |
| 831 | escaping = false; |
| 832 | saw_boundary = true; |
| 833 | } else if character == '\\' { |
| 834 | escaping = true; |
| 835 | } else if character == '\'' { |
| 836 | state = State::Single; |
| 837 | saw_boundary = true; |
| 838 | } else if character == '"' { |
| 839 | state = State::Double; |
| 840 | saw_boundary = true; |
| 841 | } else if character.is_whitespace() { |
| 842 | if !current.is_empty() || saw_boundary { |
| 843 | tokens.push(std::mem::take(&mut current)); |
| 844 | saw_boundary = false; |
| 845 | } |
| 846 | } else { |
| 847 | current.push(character); |
| 848 | saw_boundary = true; |
| 849 | } |
| 850 | } |
| 851 | State::Single => { |
| 852 | if character == '\'' { |
| 853 | state = State::Normal; |
| 854 | } else { |
| 855 | current.push(character); |
| 856 | } |
| 857 | } |
| 858 | State::Double => { |
| 859 | if escaping { |
| 860 | current.push(character); |
| 861 | escaping = false; |
| 862 | } else if character == '\\' { |
| 863 | escaping = true; |
| 864 | } else if character == '"' { |
| 865 | state = State::Normal; |
| 866 | } else { |
| 867 | current.push(character); |
| 868 | } |
| 869 | } |
| 870 | } |
| 871 | } |
| 872 | if escaping { |
no test coverage detected