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

gripmock / grpctestify-rust / 24368489201

13 Apr 2026 09:44PM UTC coverage: 76.048% (+0.6%) from 75.445%
24368489201

Pull #35

github

web-flow
Merge 745330ff7 into 4ba0f08f1
Pull Request #35: feat: meta section & refactoring

2754 of 3728 new or added lines in 47 files covered. (73.87%)

155 existing lines in 9 files now uncovered.

17097 of 22482 relevant lines covered (76.05%)

2480.3 hits per line

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

84.72
/src/parser/json_stream_parser.rs
1
//! Streaming JSON parser for RESPONSE sections.
2
//!
3
//! Parses multiple JSON values from a single section block by tracking
4
//! depth, string state, and escape characters — a state-machine approach
5
//! that handles JSON5 with comments.
6

7
use crate::parser::json_mod;
8

9
/// Parse multiple JSON values from a single content string.
10
///
11
/// Used for streaming response sections where multiple JSON objects
12
/// are concatenated (e.g., NDJSON or concatenated JSON5).
13
///
14
/// Returns `Some(values)` if 2+ values were successfully parsed, `None` otherwise.
15
pub fn parse_response_json_values(content: &str) -> Option<Vec<serde_json::Value>> {
13✔
16
    let mut values = Vec::new();
13✔
17
    let mut current_lines: Vec<&str> = Vec::new();
13✔
18
    let mut depth: i32 = 0;
13✔
19
    let mut in_string = false;
13✔
20
    let mut escaped = false;
13✔
21
    let mut started = false;
13✔
22

23
    for line in content.lines() {
62✔
24
        let trimmed = line.trim();
62✔
25
        if trimmed.is_empty() && current_lines.is_empty() {
62✔
NEW
26
            continue;
×
27
        }
62✔
28

29
        current_lines.push(line);
62✔
30

31
        let mut chars = line.chars().peekable();
62✔
32
        while let Some(ch) = chars.next() {
608✔
33
            if escaped {
550✔
NEW
34
                escaped = false;
×
NEW
35
                continue;
×
36
            }
550✔
37

38
            if ch == '\\' {
550✔
NEW
39
                escaped = true;
×
NEW
40
                continue;
×
41
            }
550✔
42

43
            if ch == '"' {
550✔
44
                in_string = !in_string;
96✔
45
                started = true;
96✔
46
                continue;
96✔
47
            }
454✔
48

49
            if in_string {
454✔
50
                continue;
278✔
51
            }
176✔
52

53
            if ch == '#' {
176✔
54
                break;
2✔
55
            }
174✔
56
            if ch == '/'
174✔
57
                && let Some('/') = chars.peek()
2✔
58
            {
59
                break;
2✔
60
            }
172✔
61

62
            match ch {
120✔
63
                '{' | '[' => {
26✔
64
                    depth += 1;
26✔
65
                    started = true;
26✔
66
                }
26✔
67
                '}' | ']' => {
68
                    depth -= 1;
26✔
69
                    started = true;
26✔
70
                    if depth < 0 {
26✔
NEW
71
                        return None;
×
72
                    }
26✔
73
                }
74
                c if !c.is_whitespace() => {
120✔
75
                    started = true;
72✔
76
                }
72✔
77
                _ => {}
48✔
78
            }
79
        }
80

81
        if started && depth == 0 {
62✔
82
            let chunk = current_lines.join("\n");
26✔
83
            let chunk = chunk.trim();
26✔
84
            if chunk.is_empty() {
26✔
NEW
85
                current_lines.clear();
×
NEW
86
                started = false;
×
NEW
87
                continue;
×
88
            }
26✔
89

90
            let value = json_mod::from_str(chunk).ok()?;
26✔
91
            values.push(value);
26✔
92
            current_lines.clear();
26✔
93
            started = false;
26✔
94
        }
36✔
95
    }
96

97
    if !current_lines.is_empty() {
13✔
NEW
98
        return None;
×
99
    }
13✔
100

101
    if values.len() >= 2 {
13✔
102
        Some(values)
13✔
103
    } else {
NEW
104
        None
×
105
    }
106
}
13✔
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