/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 | | } |