• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

0b10011 / oxiplate / 21334516640

25 Jan 2026 02:53PM UTC coverage: 94.918% (-3.1%) from 98.061%
21334516640

Pull #136

github

web-flow
Merge a913a8614 into fd590cb7b
Pull Request #136: feat: replaced nom with in-tree parser

2152 of 2356 new or added lines in 57 files covered. (91.34%)

5 existing lines in 1 file now uncovered.

5510 of 5805 relevant lines covered (94.92%)

5704.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.64
/oxiplate-derive/src/tokenizer/parser/expression/string.rs
1
use crate::Source;
2
use crate::tokenizer::buffered_source::BufferedSource;
3
use crate::tokenizer::{Context, ParseError, Token, TokenKind};
4

5
fn parse_string(source: &mut BufferedSource) -> Result<String, ParseError> {
161✔
6
    let mut string = String::new();
161✔
7
    while let Some(char) = source.next() {
1,941✔
8
        if char == '"' {
1,939✔
9
            return Ok(string);
159✔
10
        }
1,780✔
11

12
        string.push(char);
1,780✔
13
    }
14

15
    Err(ParseError {
2✔
16
        message: "Unclosed string".to_string(),
2✔
17
    })
2✔
18
}
161✔
19

20
pub fn consume_string<'a>(
161✔
21
    source: &mut BufferedSource<'a>,
161✔
22
    leading_whitespace: Option<Source<'a>>,
161✔
23
) -> (Option<Context>, Token<'a>) {
161✔
24
    match parse_string(source) {
161✔
25
        Ok(string) => {
159✔
26
            let source = source
159✔
27
                .consume()
159✔
28
                .expect("Buffer should contain `\"` at least");
159✔
29

30
            (
159✔
31
                None,
159✔
32
                Token::new(TokenKind::String(string), &source, leading_whitespace),
159✔
33
            )
159✔
34
        }
35
        Err(parse_error) => {
2✔
36
            let source = source
2✔
37
                .consume()
2✔
38
                .expect("Buffer should contain `\"` at least");
2✔
39

40
            (
2✔
41
                None,
2✔
42
                Token::new(
2✔
43
                    TokenKind::Unexpected(parse_error),
2✔
44
                    &source,
2✔
45
                    leading_whitespace,
2✔
46
                ),
2✔
47
            )
2✔
48
        }
49
    }
50
}
161✔
51

52
pub fn consume_raw_string<'a>(
3✔
53
    source: &mut BufferedSource<'a>,
3✔
54
    leading_whitespace: Option<Source<'a>>,
3✔
55
) -> (Option<Context>, Token<'a>) {
3✔
56
    let mut string = String::new();
3✔
57

58
    let opening_hashes = 1 + source.next_while(|char| char == '#');
5✔
59

60
    if !source.next_if(|char| char == '"') {
3✔
NEW
61
        let source = source
×
NEW
62
            .consume()
×
NEW
63
            .expect("At least one `#` should be in the buffer");
×
NEW
64
        return (
×
NEW
65
            None,
×
NEW
66
            Token::new(
×
NEW
67
                TokenKind::Unexpected(ParseError {
×
NEW
68
                    message: "Malformed raw string. Expected `\"` after opening hashes".to_string(),
×
NEW
69
                }),
×
NEW
70
                &source,
×
NEW
71
                leading_whitespace,
×
NEW
72
            ),
×
NEW
73
        );
×
74
    }
3✔
75

76
    while let Some(char) = source.next() {
60✔
77
        match char {
59✔
78
            '"' => {
79
                // Check if hashes after the `"` match the hashes before the string
80
                let closing_hashes = source.next_while(|char| char == '#');
12✔
81

82
                if closing_hashes == opening_hashes {
7✔
83
                    let source = source
2✔
84
                        .consume()
2✔
85
                        .expect("Full string should be in the buffer");
2✔
86
                    return (
2✔
87
                        None,
2✔
88
                        Token::new(TokenKind::RawString(string), &source, leading_whitespace),
2✔
89
                    );
2✔
90
                } else if closing_hashes > opening_hashes {
5✔
NEW
91
                    let source = source
×
NEW
92
                        .consume()
×
NEW
93
                        .expect("Full string plus extra hashes should be in the buffer");
×
NEW
94
                    return (
×
NEW
95
                        None,
×
NEW
96
                        Token::new(
×
NEW
97
                            TokenKind::Unexpected(ParseError {
×
NEW
98
                                message: format!(
×
NEW
99
                                    "Expected {opening_hashes} closing hashes, found \
×
NEW
100
                                     {closing_hashes}",
×
NEW
101
                                ),
×
NEW
102
                            }),
×
NEW
103
                            &source,
×
NEW
104
                            leading_whitespace,
×
NEW
105
                        ),
×
NEW
106
                    );
×
107
                }
5✔
108

109
                // Append the `"` and hashes to the string
110
                string.push('"');
5✔
111
                string.push_str(&"#".repeat(closing_hashes));
5✔
112
            }
113
            _ => {
52✔
114
                string.push(char);
52✔
115
            }
52✔
116
        }
117
    }
118

119
    let source = source
1✔
120
        .consume()
1✔
121
        .expect("At least one `#` should be in the buffer");
1✔
122

123
    (
1✔
124
        None,
1✔
125
        Token::new(
1✔
126
            TokenKind::Unexpected(ParseError {
1✔
127
                message: "Raw string never closed".to_string(),
1✔
128
            }),
1✔
129
            &source,
1✔
130
            leading_whitespace,
1✔
131
        ),
1✔
132
    )
1✔
133
}
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc