Skip to content

Commit f95c36b

Browse files
committed
Add parser.with_eol() shorthand for parser.with_suffix(parser::eol())
1 parent 9146d8e commit f95c36b

File tree

23 files changed

+90
-37
lines changed

23 files changed

+90
-37
lines changed

crates/utils/src/parser/base.rs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub type ParseResult<'i, T> = Result<(T, &'i [u8]), (ParseError, &'i [u8])>;
1414
/// Parser trait.
1515
///
1616
/// Implementations should avoid allocating where possible.
17+
#[must_use]
1718
pub trait Parser<'i>: Sized {
1819
/// Type of the value produced by [`parse`](Self::parse) when successful.
1920
type Output;
@@ -54,6 +55,7 @@ pub trait Parser<'i>: Sized {
5455
/// Ok(((123, -123), &b""[..]))
5556
/// );
5657
/// ```
58+
#[inline]
5759
fn then<T: Parser<'i>>(self, next: T) -> Self::Then<T> {
5860
Then::then(self, next)
5961
}
@@ -81,6 +83,7 @@ pub trait Parser<'i>: Sized {
8183
/// Ok((1000, &b""[..]))
8284
/// );
8385
/// ```
86+
#[inline]
8487
fn or<T: Parser<'i, Output = Self::Output>>(self, alternative: T) -> Or<Self, T> {
8588
Or {
8689
first: self,
@@ -112,6 +115,7 @@ pub trait Parser<'i>: Sized {
112115
/// Ok(((&b"123"[..], &[1, 2, 3][..]), &b""[..]))
113116
/// );
114117
/// ```
118+
#[inline]
115119
fn map<O, F: Fn(Self::Output) -> O>(self, f: F) -> Map<Self, F> {
116120
Map {
117121
parser: self,
@@ -155,6 +159,7 @@ pub trait Parser<'i>: Sized {
155159
/// Ok(((&b"123"[..], &[1, 2, 3][..]), &b""[..]))
156160
/// );
157161
/// ```
162+
#[inline]
158163
fn map_res<O, F: Fn(Self::Output) -> Result<O, &'static str>>(
159164
self,
160165
f: F,
@@ -181,6 +186,7 @@ pub trait Parser<'i>: Sized {
181186
/// Ok((None, &b"abc"[..]))
182187
/// );
183188
/// ```
189+
#[inline]
184190
fn optional(self) -> Optional<Self> {
185191
Optional { parser: self }
186192
}
@@ -200,6 +206,7 @@ pub trait Parser<'i>: Sized {
200206
/// Ok(([12, 34, 56], &b""[..]))
201207
/// );
202208
/// ```
209+
#[inline]
203210
fn repeat_n<const N: usize, S: Parser<'i>>(self, separator: S) -> RepeatN<N, Self, S>
204211
where
205212
Self::Output: Copy + Default,
@@ -225,6 +232,7 @@ pub trait Parser<'i>: Sized {
225232
/// assert_eq!(parser.parse(b"12,34,56,78"), Ok((vec![12, 34, 56, 78], &b""[..])));
226233
/// assert!(parser.parse(b"12,34").is_err());
227234
/// ```
235+
#[inline]
228236
fn repeat_arrayvec<const N: usize, S: Parser<'i>>(
229237
self,
230238
separator: S,
@@ -254,6 +262,7 @@ pub trait Parser<'i>: Sized {
254262
/// assert_eq!(parser.parse(b"12,34,56,78"), Ok((vec![12, 34, 56, 78], &b""[..])));
255263
/// assert!(parser.parse(b"12,34").is_err());
256264
/// ```
265+
#[inline]
257266
fn repeat<S: Parser<'i>>(self, separator: S, min_elements: usize) -> RepeatVec<Self, S> {
258267
RepeatVec {
259268
parser: self,
@@ -275,6 +284,7 @@ pub trait Parser<'i>: Sized {
275284
/// Ok(((12, &b"012"[..]), &b",345,678"[..]))
276285
/// );
277286
/// ```
287+
#[inline]
278288
fn with_consumed(self) -> WithConsumed<Self> {
279289
WithConsumed { parser: self }
280290
}
@@ -293,6 +303,7 @@ pub trait Parser<'i>: Sized {
293303
/// Ok((123, &b""[..]))
294304
/// );
295305
/// ```
306+
#[inline]
296307
fn with_prefix<T: Parser<'i>>(self, prefix: T) -> WithPrefix<Self, T> {
297308
WithPrefix {
298309
parser: self,
@@ -314,13 +325,35 @@ pub trait Parser<'i>: Sized {
314325
/// Ok((123, &b""[..]))
315326
/// );
316327
/// ```
328+
#[inline]
317329
fn with_suffix<T: Parser<'i>>(self, suffix: T) -> WithSuffix<Self, T> {
318330
WithSuffix {
319331
parser: self,
320332
suffix,
321333
}
322334
}
323335

336+
/// Parse a end of line (or end of string) after this parser.
337+
///
338+
/// Equivalent to [`parser.with_suffix`](Parser::with_suffix)`(`[`parser::eol()`](super::eol)`)`.
339+
///
340+
/// # Examples
341+
/// ```
342+
/// # use utils::parser::{self, Parser};
343+
/// assert_eq!(
344+
/// parser::u32().with_eol()
345+
/// .parse(b"123\nabc"),
346+
/// Ok((123, &b"abc"[..]))
347+
/// );
348+
/// ```
349+
#[inline]
350+
fn with_eol(self) -> WithSuffix<Self, Eol> {
351+
WithSuffix {
352+
parser: self,
353+
suffix: Eol(),
354+
}
355+
}
356+
324357
/// Replace this parser's error message with the provided string.
325358
///
326359
/// # Examples
@@ -337,6 +370,7 @@ pub trait Parser<'i>: Sized {
337370
/// Err((ParseError::Custom("expected power level"), &b"abc"[..]))
338371
/// );
339372
/// ```
373+
#[inline]
340374
fn error_msg(self, message: &'static str) -> WithErrorMsg<Self> {
341375
WithErrorMsg {
342376
parser: self,
@@ -352,6 +386,7 @@ pub trait Parser<'i>: Sized {
352386
/// assert_eq!(parser::u32().parse_complete("1234").unwrap(), 1234);
353387
/// assert!(parser::u32().parse_complete("1234abc").is_err());
354388
/// ```
389+
#[inline]
355390
fn parse_complete(&self, input: &'i str) -> Result<Self::Output, InputError> {
356391
match self.parse(input.as_bytes()).map_with_input(input)? {
357392
(v, []) => Ok(v),
@@ -379,6 +414,7 @@ pub trait Parser<'i>: Sized {
379414
/// ]
380415
/// );
381416
/// ```
417+
#[inline]
382418
fn parse_all(&self, input: &'i str) -> Result<Vec<Self::Output>, InputError> {
383419
ParserRef(self)
384420
.repeat(Constant(()), 0)
@@ -387,7 +423,7 @@ pub trait Parser<'i>: Sized {
387423

388424
/// Similar to [`parse_all`](Self::parse_all) but expects a newline after each item.
389425
///
390-
/// Equivalent to `parser.with_suffix(`[`parser::eol()`](super::eol)`).parse_all(input)`.
426+
/// Equivalent to [`parser.with_eol()`](Parser::with_eol)`.parse_all(input)`.
391427
///
392428
/// # Examples
393429
/// ```
@@ -404,6 +440,7 @@ pub trait Parser<'i>: Sized {
404440
/// ]
405441
/// );
406442
/// ```
443+
#[inline]
407444
fn parse_lines(&self, input: &'i str) -> Result<Vec<Self::Output>, InputError> {
408445
ParserRef(self)
409446
.with_suffix(Eol())
@@ -423,7 +460,7 @@ pub trait Parser<'i>: Sized {
423460
/// # use utils::input::InputError;
424461
/// # use utils::parser::{self, Parser};
425462
/// let iterator = parser::u32()
426-
/// .with_suffix(parser::eol())
463+
/// .with_eol()
427464
/// .parse_iterator("12\n34\n56\n78");
428465
/// for item in iterator {
429466
/// println!("{}", item?);
@@ -434,7 +471,7 @@ pub trait Parser<'i>: Sized {
434471
/// ```
435472
/// # use utils::parser::{self, Parser};
436473
/// let mut iterator = parser::u32()
437-
/// .with_suffix(parser::eol())
474+
/// .with_eol()
438475
/// .parse_iterator("12\n34\nnot a integer");
439476
/// assert_eq!(iterator.next().unwrap().unwrap(), 12);
440477
/// assert_eq!(iterator.next().unwrap().unwrap(), 34);
@@ -446,13 +483,14 @@ pub trait Parser<'i>: Sized {
446483
/// # use utils::input::InputError;
447484
/// # use utils::parser::{self, Parser};
448485
/// let filtered = parser::u32()
449-
/// .with_suffix(parser::eol())
486+
/// .with_eol()
450487
/// .parse_iterator("11\n22\n33\n44\n55")
451488
/// .filter(|r| r.is_err() || r.as_ref().is_ok_and(|v| v % 2 == 0))
452489
/// .collect::<Result<Vec<u32>, InputError>>()?;
453490
/// assert_eq!(filtered, vec![22, 44]);
454491
/// # Ok::<(), InputError>(())
455492
/// ```
493+
#[inline]
456494
fn parse_iterator(self, input: &str) -> ParserIterator<'_, Self> {
457495
ParserIterator {
458496
input,
@@ -477,6 +515,7 @@ pub trait Parser<'i>: Sized {
477515
/// vec![123, 456, 7, 8, 9]
478516
/// );
479517
/// ```
518+
#[inline]
480519
fn matches_iterator(self, input: &str) -> ParserMatchesIterator<'_, Self> {
481520
ParserMatchesIterator {
482521
remaining: input.as_bytes(),

crates/utils/src/parser/iterator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl<'a, P: Parser<'a>> ParserIterator<'a, P> {
4545
/// # use utils::input::InputError;
4646
/// # use utils::parser::{self, Parser};
4747
/// let mut iterator = parser::u32()
48-
/// .with_suffix(parser::eol())
48+
/// .with_eol()
4949
/// .parse_iterator("12\n34\n56\n78");
5050
/// assert_eq!(iterator.next().unwrap().unwrap(), 12);
5151
/// assert_eq!(iterator.next().unwrap().unwrap(), 34);

crates/utils/src/parser/number.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ macro_rules! parser_for {
8383
}
8484

8585
#[doc = concat!("Parser for [`prim@", stringify!($n), "`] values.")]
86+
#[inline]
8687
#[must_use]
8788
pub fn $n() -> $p<std::primitive::$n> {
8889
$p(PhantomData)

crates/utils/src/parser/one_of.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ impl<'i, O: ParserOneOfTuple<'i>> Parser<'i> for OneOf<O> {
113113
/// ParseError::NumberTooSmall(-2147483648)
114114
/// );
115115
/// ```
116+
#[inline]
117+
#[must_use]
116118
pub fn one_of<'i, L: ParserOneOfTuple<'i>>(options: L) -> OneOf<L> {
117119
OneOf { options }
118120
}

crates/utils/src/parser/simple.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ impl<'i> Parser<'i> for Byte {
3434
/// Ok((b'1', &b"23"[..]))
3535
/// );
3636
/// ```
37+
#[inline]
3738
#[must_use]
3839
pub fn byte() -> Byte {
3940
Byte()
@@ -155,6 +156,7 @@ impl<'i, V: Copy> Parser<'i> for Constant<V> {
155156
/// Ok((1, &b"abc"[..]))
156157
/// );
157158
/// ```
159+
#[inline]
158160
#[must_use]
159161
pub fn constant<T: Copy>(v: T) -> Constant<T> {
160162
Constant(v)
@@ -170,6 +172,7 @@ pub fn constant<T: Copy>(v: T) -> Constant<T> {
170172
/// Ok(((), &b"abc"[..]))
171173
/// );
172174
/// ```
175+
#[inline]
173176
#[must_use]
174177
pub fn noop() -> Constant<()> {
175178
const {
@@ -217,6 +220,7 @@ impl<'i> Parser<'i> for Eof {
217220
/// vec![12, 34, 56],
218221
/// );
219222
/// ```
223+
#[inline]
220224
#[must_use]
221225
pub fn eof() -> Eof {
222226
Eof()
@@ -258,6 +262,7 @@ impl<'i> Parser<'i> for Eol {
258262
/// Ok(((), &b""[..]))
259263
/// );
260264
/// ```
265+
#[inline]
261266
#[must_use]
262267
pub fn eol() -> Eol {
263268
Eol()
@@ -298,6 +303,7 @@ impl<'i, const N: usize> Parser<'i> for TakeWhile<N> {
298303
/// Ok((&b""[..], &b"ABC"[..]))
299304
/// );
300305
/// ```
306+
#[inline]
301307
#[must_use]
302308
pub fn take_while(f: fn(&u8) -> bool) -> TakeWhile<0> {
303309
TakeWhile(f)
@@ -315,6 +321,7 @@ pub fn take_while(f: fn(&u8) -> bool) -> TakeWhile<0> {
315321
/// );
316322
/// assert!(parser.parse(b"ABC").is_err());
317323
/// ```
324+
#[inline]
318325
#[must_use]
319326
pub fn take_while1(f: fn(&u8) -> bool) -> TakeWhile<1> {
320327
TakeWhile(f)

crates/year2015/src/day21.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ impl Day21 {
2424
pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
2525
let (boss_health, boss_damage, boss_armor) = parser::u32()
2626
.with_prefix("Hit Points: ")
27-
.then(parser::u32().with_prefix(parser::eol().then("Damage: ")))
28-
.then(parser::u32().with_prefix(parser::eol().then("Armor: ")))
27+
.with_eol()
28+
.then(parser::u32().with_prefix("Damage: ").with_eol())
29+
.then(parser::u32().with_prefix("Armor: "))
2930
.parse_complete(input)?;
3031

3132
let mut min_gold_win = u32::MAX;

crates/year2015/src/day22.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ impl Day22 {
1111
pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
1212
let (boss_health, boss_damage) = parser::u32()
1313
.with_prefix("Hit Points: ")
14-
.with_suffix(parser::eol())
14+
.with_eol()
1515
.then(parser::u32().with_prefix("Damage: "))
1616
.parse_complete(input)?;
1717

crates/year2016/src/day08.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl Day08 {
3333

3434
let mut grid = [[false; 50]; 6];
3535
for item in parser::one_of((rect, rotate_row, rotate_col))
36-
.with_suffix(parser::eol())
36+
.with_eol()
3737
.parse_iterator(input)
3838
{
3939
match item? {

crates/year2017/src/day08.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl Day08 {
3232
.with_suffix(" "),
3333
)
3434
.then(parser::i32())
35-
.with_suffix(parser::eol())
35+
.with_eol()
3636
.parse_iterator(input);
3737

3838
let mut registers = HashMap::new();

crates/year2017/src/day15.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl Day15 {
3232
pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
3333
let (start_a, start_b) = parser::u32()
3434
.with_prefix("Generator A starts with ")
35-
.with_suffix(parser::eol())
35+
.with_eol()
3636
.then(parser::u32().with_prefix("Generator B starts with "))
3737
.parse_complete(input)?;
3838

0 commit comments

Comments
 (0)