async_graphql_parser/
pos.rs1use std::{
2 borrow::{Borrow, BorrowMut},
3 cmp::Ordering,
4 fmt,
5 hash::{Hash, Hasher},
6};
7
8use pest::{iterators::Pair, RuleType};
9use serde::{Deserialize, Serialize};
10
11#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Default, Hash, Serialize, Deserialize)]
16pub struct Pos {
17 pub line: usize,
19
20 pub column: usize,
22}
23
24impl fmt::Debug for Pos {
25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26 write!(f, "Pos({}:{})", self.line, self.column)
27 }
28}
29
30impl fmt::Display for Pos {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 write!(f, "{}:{}", self.line, self.column)
33 }
34}
35
36impl From<(usize, usize)> for Pos {
37 fn from((line, column): (usize, usize)) -> Self {
38 Self { line, column }
39 }
40}
41
42#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
44pub struct Positioned<T: ?Sized> {
45 pub pos: Pos,
47 pub node: T,
49}
50
51impl<T> Positioned<T> {
52 #[must_use]
54 pub const fn new(node: T, pos: Pos) -> Positioned<T> {
55 Positioned { pos, node }
56 }
57
58 #[inline]
63 pub fn into_inner(self) -> T {
64 self.node
65 }
66
67 #[must_use]
69 pub fn position_node<U>(&self, other: U) -> Positioned<U> {
70 Positioned::new(other, self.pos)
71 }
72
73 #[must_use]
75 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Positioned<U> {
76 Positioned::new(f(self.node), self.pos)
77 }
78}
79
80impl<T: fmt::Display> fmt::Display for Positioned<T> {
81 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82 self.node.fmt(f)
83 }
84}
85impl<T: PartialEq> PartialEq for Positioned<T> {
86 fn eq(&self, other: &Self) -> bool {
87 self.node == other.node
88 }
89}
90impl<T: Eq> Eq for Positioned<T> {}
91impl<T: PartialOrd> PartialOrd for Positioned<T> {
92 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
93 self.node.partial_cmp(&other.node)
94 }
95}
96impl<T: Ord> Ord for Positioned<T> {
97 fn cmp(&self, other: &Self) -> Ordering {
98 self.node.cmp(&other.node)
99 }
100}
101impl<T: Hash> Hash for Positioned<T> {
102 fn hash<H: Hasher>(&self, state: &mut H) {
103 self.node.hash(state)
104 }
105}
106
107impl Borrow<str> for Positioned<String> {
108 fn borrow(&self) -> &str {
109 self.node.as_str()
110 }
111}
112
113impl BorrowMut<str> for Positioned<String> {
114 fn borrow_mut(&mut self) -> &mut str {
115 self.node.as_mut_str()
116 }
117}
118
119pub(crate) struct PositionCalculator<'a> {
120 input: &'a str,
121 pos: usize,
122 line: usize,
123 column: usize,
124}
125
126impl<'a> PositionCalculator<'a> {
127 pub(crate) fn new(input: &'a str) -> PositionCalculator<'a> {
128 Self {
129 input,
130 pos: 0,
131 line: 1,
132 column: 1,
133 }
134 }
135
136 pub(crate) fn step<R: RuleType>(&mut self, pair: &Pair<R>) -> Pos {
137 let pos = pair.as_span().start();
138 debug_assert!(pos >= self.pos);
139 let bytes_to_read = pos - self.pos;
140 let chars_to_read = self.input[..bytes_to_read].chars();
141 for ch in chars_to_read {
142 match ch {
143 '\r' => {
144 self.column = 1;
145 }
146 '\n' => {
147 self.line += 1;
148 self.column = 1;
149 }
150 _ => {
151 self.column += 1;
152 }
153 }
154 }
155 self.pos = pos;
156 self.input = &self.input[bytes_to_read..];
157 Pos {
158 line: self.line,
159 column: self.column,
160 }
161 }
162}