112 lines
4.1 KiB
Rust
112 lines
4.1 KiB
Rust
![]() |
/// Interface for a source of characters.
|
||
|
///
|
||
|
/// Hiding the input's implementation behind this trait allows mostly:
|
||
|
/// * For input-specific optimizations (for instance, using `str` methods instead of manually
|
||
|
/// transferring one `char` at a time to a buffer).
|
||
|
/// * To return `&str`s referencing the input string, thus avoiding potentially costly
|
||
|
/// allocations. Should users need an owned version of the data, they can always `.to_owned()`
|
||
|
/// their YAML object.
|
||
|
pub trait Input {
|
||
|
/// A hint to the input source that we will need to read `count` characters.
|
||
|
///
|
||
|
/// If the input is exhausted, `\0` can be used to pad the last characters and later returned.
|
||
|
/// The characters must not be consumed, but may be placed in an internal buffer.
|
||
|
///
|
||
|
/// This method may be a no-op if buffering yields no performance improvement.
|
||
|
///
|
||
|
/// Implementers of [`Input`] must _not_ load more than `count` characters into the buffer. The
|
||
|
/// parser tracks how many characters are loaded in the buffer and acts accordingly.
|
||
|
fn lookahead(&mut self, count: usize);
|
||
|
|
||
|
/// Return the number of buffered characters in `self`.
|
||
|
#[must_use]
|
||
|
fn buflen(&self) -> usize;
|
||
|
|
||
|
/// Return the capacity of the buffer in `self`.
|
||
|
#[must_use]
|
||
|
fn bufmaxlen(&self) -> usize;
|
||
|
|
||
|
/// Return whether the buffer (!= stream) is empty.
|
||
|
#[inline]
|
||
|
#[must_use]
|
||
|
fn buf_is_empty(&self) -> bool {
|
||
|
self.buflen() == 0
|
||
|
}
|
||
|
|
||
|
/// Read a character from the input stream and return it directly.
|
||
|
///
|
||
|
/// The internal buffer (is any) is bypassed.
|
||
|
#[must_use]
|
||
|
fn raw_read_ch(&mut self) -> char;
|
||
|
|
||
|
/// Put a character back in the buffer.
|
||
|
///
|
||
|
/// This function is only called when we read one too many characters and the pushed back
|
||
|
/// character is exactly the last character that was read. This function will not be called
|
||
|
/// multiple times consecutively.
|
||
|
fn push_back(&mut self, c: char);
|
||
|
|
||
|
/// Consume the next character.
|
||
|
fn skip(&mut self);
|
||
|
|
||
|
/// Consume the next `count` character.
|
||
|
fn skip_n(&mut self, count: usize);
|
||
|
|
||
|
/// Return the next character, without consuming it.
|
||
|
///
|
||
|
/// Users of the [`Input`] must make sure that the character has been loaded through a prior
|
||
|
/// call to [`Input::lookahead`]. Implementors of [`Input`] may assume that a valid call to
|
||
|
/// [`Input::lookahead`] has been made beforehand.
|
||
|
///
|
||
|
/// # Return
|
||
|
/// If the input source is not exhausted, returns the next character to be fed into the
|
||
|
/// scanner. Otherwise, returns `\0`.
|
||
|
#[must_use]
|
||
|
fn peek(&self) -> char;
|
||
|
|
||
|
/// Return the `n`-th character in the buffer, without consuming it.
|
||
|
///
|
||
|
/// This function assumes that the n-th character in the input has already been fetched through
|
||
|
/// [`Input::lookahead`].
|
||
|
#[must_use]
|
||
|
fn peek_nth(&self, n: usize) -> char;
|
||
|
|
||
|
/// Look for the next character and return it.
|
||
|
///
|
||
|
/// The character is not consumed.
|
||
|
/// Equivalent to calling [`Input::lookahead`] and [`Input::peek`].
|
||
|
#[inline]
|
||
|
#[must_use]
|
||
|
fn look_ch(&mut self) -> char {
|
||
|
self.lookahead(1);
|
||
|
self.peek()
|
||
|
}
|
||
|
|
||
|
/// Return whether the next character in the input source is equal to `c`.
|
||
|
///
|
||
|
/// This function assumes that the next character in the input has already been fetched through
|
||
|
/// [`Input::lookahead`].
|
||
|
#[inline]
|
||
|
#[must_use]
|
||
|
fn next_char_is(&self, c: char) -> bool {
|
||
|
self.peek() == c
|
||
|
}
|
||
|
|
||
|
/// Return whether the `n`-th character in the input source is equal to `c`.
|
||
|
///
|
||
|
/// This function assumes that the n-th character in the input has already been fetched through
|
||
|
/// [`Input::lookahead`].
|
||
|
#[inline]
|
||
|
#[must_use]
|
||
|
fn nth_char_is(&self, n: usize, c: char) -> bool {
|
||
|
self.peek_nth(n) == c
|
||
|
}
|
||
|
|
||
|
/// Return whether the next characters in the input source match the given pattern.
|
||
|
///
|
||
|
/// This function assumes that the next `pat.len()` characters in the input has already been
|
||
|
/// fetched through [`Input::lookahead`].
|
||
|
#[must_use]
|
||
|
fn next_is(&self, pat: &str) -> bool;
|
||
|
}
|