1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
use super::{ErrorKind, ParseDirection, ParseError, Parser};
use crate::string;
// Putting this impl in a submodule so that it appears before
// the integer parsing methods in the docs
impl<'a> Parser<'a> {
/// Constructs a Parser from a string.
///
/// This parser start with a `start_offset` of `0`,
/// [`with_start_offset`](Self::with_start_offset)
/// is preferable for parsing after the start of a string.
#[inline]
pub const fn new(string: &'a str) -> Self {
Self {
parse_direction: ParseDirection::FromStart,
start_offset: 0,
yielded_last_split: false,
str: string,
}
}
/// Constructs a Parser from `string` which is at `start_offset`
/// inside some other string.
///
/// # Example
///
/// ```rust
/// use konst::parsing::{ErrorKind, Parser};
///
/// // indices
/// // 0 4 8
/// // | | |
/// // "foo bar baz"
/// let substr = konst::string::str_from("foo bar baz", 4);
///
/// let mut parser = Parser::with_start_offset(substr, 4);
/// assert_eq!(parser.remainder(), "bar baz");
///
/// let bar = parser.split(' ').unwrap();
/// assert_eq!(bar, "bar");
///
/// let err = parser.split_terminator(' ').unwrap_err();
///
/// assert_eq!(parser.remainder(), "baz");
/// assert_eq!(err.offset(), 8);
/// assert_eq!(err.kind(), ErrorKind::DelimiterNotFound);
///
/// ```
#[inline]
pub const fn with_start_offset(string: &'a str, start_offset: usize) -> Self {
Self {
parse_direction: ParseDirection::FromStart,
start_offset: start_offset as u32,
yielded_last_split: false,
str: string,
}
}
/// Skips `byte_count` bytes from the parsed string,
/// as well as however many bytes are required to be on a char boundary.
///
/// This method mutates the parser in place.
///
pub const fn skip(&mut self, mut byte_count: usize) -> &mut Self {
let bytes = self.str.as_bytes();
if byte_count > bytes.len() {
byte_count = bytes.len()
} else {
use crate::string::__is_char_boundary_bytes;
while !__is_char_boundary_bytes(bytes, byte_count) {
byte_count += 1;
}
};
self.parse_direction = ParseDirection::FromStart;
self.start_offset += byte_count as u32;
self.str = string::str_from(self.str, byte_count);
self
}
/// Skips `byte_count` bytes from the back of the parsed string,
/// as well as however many bytes are required to be on a char boundary.
///
/// This method mutates the parser in place.
///
pub const fn skip_back(&mut self, byte_count: usize) -> &mut Self {
use crate::string::__is_char_boundary_bytes;
let bytes = self.str.as_bytes();
let mut pos = self.str.len().saturating_sub(byte_count);
while !__is_char_boundary_bytes(bytes, pos) {
pos -= 1;
}
self.parse_direction = ParseDirection::FromEnd;
self.str = string::str_up_to(self.str, pos);
self
}
/// Returns a bytewise copy of `Self`
#[inline(always)]
pub const fn copy(&self) -> Self {
Self { ..*self }
}
/// Returns the remaining, unparsed string.
#[inline(always)]
pub const fn remainder(&self) -> &'a str {
self.str
}
/// Gets the byte offset of this parser in the str slice that this
/// was constructed from.
#[inline(always)]
pub const fn start_offset(&self) -> usize {
self.start_offset as _
}
/// Gets the end byte offset of this parser in the str slice that this
/// was constructed from.
#[inline(always)]
pub const fn end_offset(&self) -> usize {
self.start_offset as usize + self.str.len()
}
/// The direction that the parser was last mutated from.
pub const fn parse_direction(&self) -> ParseDirection {
self.parse_direction
}
/// Constructs a [`ParseError`] for this point in parsing.
///
/// [`ParseError`]: crate::parsing::ParseError
pub const fn to_error(&self, kind: ErrorKind) -> ParseError<'a> {
ParseError::new(self, kind)
}
/// Constructs a [`ParseError`] for this point in parsing,
/// for an [`ErrorKind::Other`] with a custom error message.
///
/// [`ParseError`]: crate::parsing::ParseError
/// [`ErrorKind::Other`]: crate::parsing::ErrorKind#variant.Other
pub const fn to_other_error(&self, string: &'static &'static str) -> ParseError<'a> {
ParseError::other_error(self, string)
}
/// The amount of unparsed bytes.
#[inline(always)]
pub const fn len(&self) -> usize {
self.str.len()
}
/// Whether there are any bytes left to parse.
#[inline(always)]
pub const fn is_empty(&self) -> bool {
self.str.is_empty()
}
#[doc(hidden)]
pub const fn __borrow_mut(&mut self) -> &mut Self {
self
}
}