Coverage Report

Created: 2025-02-21 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/async-graphql-parser-7.0.15/src/pos.rs
Line
Count
Source (jump to first uncovered line)
1
use std::{
2
    borrow::{Borrow, BorrowMut},
3
    cmp::Ordering,
4
    fmt,
5
    hash::{Hash, Hasher},
6
};
7
8
use pest::{iterators::Pair, RuleType};
9
use serde::{Deserialize, Serialize};
10
11
/// Original position of an element in source code.
12
///
13
/// You can serialize and deserialize it to the GraphQL `locations` format
14
/// ([reference](https://spec.graphql.org/October2021/#sec-Errors)).
15
#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Default, Hash, Serialize, Deserialize)]
16
pub struct Pos {
17
    /// One-based line number.
18
    pub line: usize,
19
20
    /// One-based column number.
21
    pub column: usize,
22
}
23
24
impl fmt::Debug for Pos {
25
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26
0
        write!(f, "Pos({}:{})", self.line, self.column)
27
0
    }
28
}
29
30
impl fmt::Display for Pos {
31
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32
0
        write!(f, "{}:{}", self.line, self.column)
33
0
    }
34
}
35
36
impl From<(usize, usize)> for Pos {
37
0
    fn from((line, column): (usize, usize)) -> Self {
38
0
        Self { line, column }
39
0
    }
40
}
41
42
/// An AST node that stores its original position.
43
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
44
pub struct Positioned<T: ?Sized> {
45
    /// The position of the node.
46
    pub pos: Pos,
47
    /// The node itself.
48
    pub node: T,
49
}
50
51
impl<T> Positioned<T> {
52
    /// Create a new positioned node from the node and its position.
53
    #[must_use]
54
0
    pub const fn new(node: T, pos: Pos) -> Positioned<T> {
55
0
        Positioned { pos, node }
56
0
    }
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::FragmentDefinition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::OperationDefinition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_value::ConstValue>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_value::Name>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_value::Value>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::OperationType>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::ConstDirective>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::Type>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::Directive>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<serde_json::number::Number>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<alloc::string::String>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::parse::executable::FragmentDefinitionItem>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::parse::executable::OperationDefinitionItem>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::SelectionSet>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::TypeCondition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::FragmentSpread>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::InlineFragment>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::VariableDefinition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::Field>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::executable::Selection>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::TypeDefinition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::FieldDefinition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::SchemaDefinition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::DirectiveLocation>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::DirectiveDefinition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::EnumValueDefinition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::service::InputValueDefinition>>::new
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<bool>>::new
57
58
    /// Get the inner node.
59
    ///
60
    /// This is most useful in callback chains where `Positioned::into_inner` is
61
    /// easier to read than `|positioned| positioned.node`.
62
    #[inline]
63
0
    pub fn into_inner(self) -> T {
64
0
        self.node
65
0
    }
66
67
    /// Create a new positioned node with the same position as this one.
68
    #[must_use]
69
0
    pub fn position_node<U>(&self, other: U) -> Positioned<U> {
70
0
        Positioned::new(other, self.pos)
71
0
    }
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_value::Value>>::position_node::<async_graphql_value::ConstValue>
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<_>>::position_node::<_>
72
73
    /// Map the inner value of this positioned node.
74
    #[must_use]
75
0
    pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Positioned<U> {
76
0
        Positioned::new(f(self.node), self.pos)
77
0
    }
78
}
79
80
impl<T: fmt::Display> fmt::Display for Positioned<T> {
81
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82
0
        self.node.fmt(f)
83
0
    }
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_value::Name> as core::fmt::Display>::fmt
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_parser::types::Type> as core::fmt::Display>::fmt
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<_> as core::fmt::Display>::fmt
84
}
85
impl<T: PartialEq> PartialEq for Positioned<T> {
86
0
    fn eq(&self, other: &Self) -> bool {
87
0
        self.node == other.node
88
0
    }
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<async_graphql_value::Value> as core::cmp::PartialEq>::eq
Unexecuted instantiation: <async_graphql_parser::pos::Positioned<_> as core::cmp::PartialEq>::eq
89
}
90
impl<T: Eq> Eq for Positioned<T> {}
91
impl<T: PartialOrd> PartialOrd for Positioned<T> {
92
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
93
0
        self.node.partial_cmp(&other.node)
94
0
    }
95
}
96
impl<T: Ord> Ord for Positioned<T> {
97
0
    fn cmp(&self, other: &Self) -> Ordering {
98
0
        self.node.cmp(&other.node)
99
0
    }
100
}
101
impl<T: Hash> Hash for Positioned<T> {
102
0
    fn hash<H: Hasher>(&self, state: &mut H) {
103
0
        self.node.hash(state)
104
0
    }
105
}
106
107
impl Borrow<str> for Positioned<String> {
108
0
    fn borrow(&self) -> &str {
109
0
        self.node.as_str()
110
0
    }
111
}
112
113
impl BorrowMut<str> for Positioned<String> {
114
0
    fn borrow_mut(&mut self) -> &mut str {
115
0
        self.node.as_mut_str()
116
0
    }
117
}
118
119
pub(crate) struct PositionCalculator<'a> {
120
    input: &'a str,
121
    pos: usize,
122
    line: usize,
123
    column: usize,
124
}
125
126
impl<'a> PositionCalculator<'a> {
127
0
    pub(crate) fn new(input: &'a str) -> PositionCalculator<'a> {
128
0
        Self {
129
0
            input,
130
0
            pos: 0,
131
0
            line: 1,
132
0
            column: 1,
133
0
        }
134
0
    }
135
136
0
    pub(crate) fn step<R: RuleType>(&mut self, pair: &Pair<R>) -> Pos {
137
0
        let pos = pair.as_span().start();
138
0
        debug_assert!(pos >= self.pos);
139
0
        let bytes_to_read = pos - self.pos;
140
0
        let chars_to_read = self.input[..bytes_to_read].chars();
141
0
        for ch in chars_to_read {
142
0
            match ch {
143
0
                '\r' => {
144
0
                    self.column = 1;
145
0
                }
146
0
                '\n' => {
147
0
                    self.line += 1;
148
0
                    self.column = 1;
149
0
                }
150
0
                _ => {
151
0
                    self.column += 1;
152
0
                }
153
            }
154
        }
155
0
        self.pos = pos;
156
0
        self.input = &self.input[bytes_to_read..];
157
0
        Pos {
158
0
            line: self.line,
159
0
            column: self.column,
160
0
        }
161
0
    }
162
}