Coverage Report

Created: 2025-10-10 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/async-graphql-parser-7.0.16/src/parse/utils.rs
Line
Count
Source
1
use pest::iterators::{Pair, Pairs};
2
3
use super::Rule;
4
use crate::Result;
5
6
0
pub(super) fn next_if_rule<'a>(pairs: &mut Pairs<'a, Rule>, rule: Rule) -> Option<Pair<'a, Rule>> {
7
0
    if pairs.peek().is_some_and(|pair| pair.as_rule() == rule) {
8
0
        Some(pairs.next().unwrap())
9
    } else {
10
0
        None
11
    }
12
0
}
13
0
pub(super) fn parse_if_rule<T>(
14
0
    pairs: &mut Pairs<Rule>,
15
0
    rule: Rule,
16
0
    f: impl FnOnce(Pair<Rule>) -> Result<T>,
17
0
) -> Result<Option<T>> {
18
0
    next_if_rule(pairs, rule).map(f).transpose()
19
0
}
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<async_graphql_value::ConstValue>, async_graphql_parser::parse::executable::parse_variable_definition::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<async_graphql_value::ConstValue>, async_graphql_parser::parse::service::parse_input_value_definition::{closure#1}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<async_graphql_value::Name>, async_graphql_parser::parse::executable::parse_field::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<async_graphql_value::Name>, async_graphql_parser::parse::executable::parse_named_operation_definition::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<alloc::string::String>, async_graphql_parser::parse::service::parse_type_definition::{closure#6}::{closure#0}::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<alloc::string::String>, async_graphql_parser::parse::service::parse_type_definition::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<alloc::string::String>, async_graphql_parser::parse::service::parse_field_definition::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<alloc::string::String>, async_graphql_parser::parse::service::parse_directive_definition::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<alloc::string::String>, async_graphql_parser::parse::service::parse_input_value_definition::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::SelectionSet>, async_graphql_parser::parse::executable::parse_field::{closure#2}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::TypeCondition>, async_graphql_parser::parse::executable::parse_inline_fragment::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_value::Name>>, async_graphql_parser::parse::service::parse_type_definition::{closure#3}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_value::Name>>, async_graphql_parser::parse::service::parse_type_definition::{closure#5}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_value::Name>>, async_graphql_parser::parse::service::parse_type_definition::{closure#1}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_parser::types::ConstDirective>>, async_graphql_parser::parse::parse_opt_const_directives::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_parser::types::Directive>>, async_graphql_parser::parse::parse_opt_directives::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::VariableDefinition>>, async_graphql_parser::parse::executable::parse_named_operation_definition::{closure#1}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::FieldDefinition>>, async_graphql_parser::parse::service::parse_type_definition::{closure#2}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::FieldDefinition>>, async_graphql_parser::parse::service::parse_type_definition::{closure#4}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::EnumValueDefinition>>, async_graphql_parser::parse::service::parse_type_definition::{closure#6}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::InputValueDefinition>>, async_graphql_parser::parse::service::parse_type_definition::{closure#7}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::InputValueDefinition>>, async_graphql_parser::parse::service::parse_field_definition::{closure#1}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::InputValueDefinition>>, async_graphql_parser::parse::service::parse_directive_definition::{closure#1}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<(async_graphql_parser::pos::Positioned<async_graphql_value::Name>, async_graphql_parser::pos::Positioned<async_graphql_value::ConstValue>)>, async_graphql_parser::parse::parse_const_directive::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<(async_graphql_parser::pos::Positioned<async_graphql_value::Name>, async_graphql_parser::pos::Positioned<async_graphql_value::Value>)>, async_graphql_parser::parse::parse_directive::{closure#0}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<alloc::vec::Vec<(async_graphql_parser::pos::Positioned<async_graphql_value::Name>, async_graphql_parser::pos::Positioned<async_graphql_value::Value>)>, async_graphql_parser::parse::executable::parse_field::{closure#1}>
Unexecuted instantiation: async_graphql_parser::parse::utils::parse_if_rule::<(), async_graphql_parser::parse::service::parse_directive_definition::{closure#2}>
20
21
0
pub(super) fn exactly_one<T>(iter: impl IntoIterator<Item = T>) -> T {
22
0
    let mut iter = iter.into_iter();
23
0
    let res = iter.next().unwrap();
24
0
    debug_assert!(iter.next().is_none());
25
0
    res
26
0
}
27
28
0
pub(super) fn block_string_value(raw: &str) -> String {
29
    // Split the string by either \r\n, \r or \n
30
0
    let lines: Vec<_> = raw
31
0
        .split("\r\n")
32
0
        .flat_map(|s| s.split(['\r', '\n'].as_ref()))
33
0
        .collect();
34
35
    // Find the common indent
36
0
    let common_indent = lines
37
0
        .iter()
38
0
        .skip(1)
39
0
        .copied()
40
0
        .filter_map(|line| line.find(|c| c != '\t' && c != ' '))
41
0
        .min()
42
0
        .unwrap_or(0);
43
44
0
    let line_has_content = |line: &str| line.as_bytes().iter().any(|&c| c != b'\t' && c != b' ');
45
46
0
    let first_contentful_line = lines
47
0
        .iter()
48
0
        .copied()
49
0
        .position(line_has_content)
50
0
        .unwrap_or(lines.len());
51
0
    let ending_lines_start = lines
52
0
        .iter()
53
0
        .copied()
54
0
        .rposition(line_has_content)
55
0
        .map_or(0, |i| i + 1);
56
57
0
    lines
58
0
        .iter()
59
0
        .copied()
60
0
        .enumerate()
61
0
        .take(ending_lines_start)
62
0
        .skip(first_contentful_line)
63
        // Remove the common indent, but not on the first line
64
0
        .map(|(i, line)| {
65
0
            if i != 0 && line.len() >= common_indent {
66
0
                &line[common_indent..]
67
            } else {
68
0
                line
69
            }
70
0
        })
71
        // Put a newline between each line
72
0
        .enumerate()
73
0
        .flat_map(|(i, line)| {
74
0
            if i == 0 { [].as_ref() } else { ['\n'].as_ref() }
75
0
                .iter()
76
0
                .copied()
77
0
                .chain(line.chars())
78
0
        })
79
0
        .collect()
80
0
}
81
82
#[test]
83
fn test_block_string_value() {
84
    assert_eq!(block_string_value(""), "");
85
    assert_eq!(block_string_value("\r\n"), "");
86
    assert_eq!(block_string_value("\r\r\r\r\n\n\r\n\r\r"), "");
87
    assert_eq!(block_string_value("abc"), "abc");
88
    assert_eq!(
89
        block_string_value("line 1\r\n   line 2\n     line 3\r    line 4"),
90
        "line 1\nline 2\n  line 3\n line 4"
91
    );
92
    assert_eq!(
93
        block_string_value("\r\r  some text\r\n \n \n "),
94
        "some text"
95
    );
96
    assert_eq!(
97
        block_string_value(
98
            r#"
99
    a
100
    b
101
102
    c
103
"#
104
        ),
105
        "a\nb\n\nc"
106
    );
107
}
108
109
0
pub(super) fn string_value(s: &str) -> String {
110
0
    let mut chars = s.chars();
111
112
0
    std::iter::from_fn(|| {
113
0
        Some(match chars.next()? {
114
0
            '\\' => match chars.next().expect("backslash at end") {
115
0
                c @ '\"' | c @ '\\' | c @ '/' => c,
116
0
                'b' => '\x08',
117
0
                'f' => '\x0C',
118
0
                'n' => '\n',
119
0
                'r' => '\r',
120
0
                't' => '\t',
121
0
                'u' => std::char::from_u32(
122
0
                    (0..4)
123
0
                        .map(|_| chars.next().unwrap().to_digit(16).unwrap())
124
0
                        .fold(0, |acc, digit| acc * 16 + digit),
125
                )
126
0
                .unwrap(),
127
0
                _ => unreachable!(),
128
            },
129
0
            other => other,
130
        })
131
0
    })
132
0
    .collect()
133
0
}
134
135
#[test]
136
fn test_string_value() {
137
    assert_eq!(string_value("abc"), "abc");
138
    assert_eq!(string_value("\\n\\b\\u2a1A"), "\n\x08\u{2A1A}");
139
    assert_eq!(string_value("\\\"\\\\"), "\"\\");
140
}