Skip to main content

Input

Struct Input 

Source
pub struct Input<'a> { /* private fields */ }
Expand description

The pending text of one REPL entry, as the pipeline sees it.

Each time a line is fed to a Session, the session calls the pipeline with an Input holding every line of the entry so far — the first line, then the first two, and so on until the pipeline answers Status::Complete. Lines are joined with '\n' and the text always ends with one.

The input also carries its position in the session’s SourceMap: base is the global offset its first byte will occupy once the entry is committed. Lex with cursor, or offset spans by base yourself, and every span the pipeline produces — in tokens, in syntax trees, in diagnostics — is already valid against Session::sources. There is no second pass to rebase spans after the entry is accepted.

Input is a borrowed, Copy view; it lives only for the duration of the pipeline call.

§Examples

use repl_lang::{Feed, Session, Status};

let mut session = Session::new();
let feed = session.feed("1 + 2", |input| {
    assert_eq!(input.text(), "1 + 2\n");
    assert_eq!(input.number(), 1);
    Status::Complete(input.text().len())
})?;
assert!(matches!(feed, Feed::Complete { value: 6, .. }));

Implementations§

Source§

impl<'a> Input<'a>

Source

pub const fn text(&self) -> &'a str

Every line of the entry so far, joined with '\n' and ending with one.

§Examples
use repl_lang::{Feed, Session, Status};

let mut session = Session::new();
let mut seen = Vec::new();
for line in ["(1 +", " 2)"] {
    session.feed(line, |input| {
        seen.push(input.text().to_owned());
        if input.text().matches('(').count() > input.text().matches(')').count() {
            Status::Incomplete
        } else {
            Status::Complete(())
        }
    })?;
}
assert_eq!(seen, ["(1 +\n", "(1 +\n 2)\n"]);
Source

pub const fn base(&self) -> BytePos

The global position the first byte of this entry occupies in the session’s source map.

Entries are laid out end to end, so the base of entry n is the total length of entries 1 through n − 1.

§Examples
use repl_lang::{Session, Status};

let mut session = Session::new();
session.feed("abc", |_| Status::Complete(()))?; // occupies 0..4 ("abc\n")
session.feed("x", |input| {
    assert_eq!(input.base().to_u32(), 4);
    Status::Complete(())
})?;
Source

pub const fn span(&self) -> Span

The global span the whole entry will occupy: from base to the end of text.

§Examples
use repl_lang::{Session, Span, Status};

let mut session = Session::new();
session.feed("let x = 1", |input| {
    assert_eq!(input.span(), Span::new(0, 10));
    Status::Complete(())
})?;
Source

pub const fn number(&self) -> u32

The entry number this input will be committed as, counting from 1.

Useful for prompts (In [3]:) and for names the evaluator binds per entry (_3). The number does not advance while an entry is incomplete, and blank lines never consume one.

§Examples
use repl_lang::{Session, Status};

let mut session = Session::new();
session.feed("a", |input| { assert_eq!(input.number(), 1); Status::Complete(()) })?;
session.feed("b", |input| { assert_eq!(input.number(), 2); Status::Complete(()) })?;
Source

pub fn cursor(&self) -> Cursor<'a>

A lexer_lang::Cursor over text, positioned at base.

Every token span the cursor produces is a global span in the session’s source map, so tokens, the syntax built from them, and any diagnostic pointing at them render correctly against Session::sources once the entry is committed.

§Examples
use repl_lang::{Session, Status};

let mut session = Session::new();
session.feed("first", |_| Status::Complete(()))?; // 0..6
session.feed("ab", |input| {
    let mut cursor = input.cursor();
    cursor.eat_while(|c| c.is_alphabetic());
    assert_eq!(cursor.lexeme(), "ab");
    assert_eq!(cursor.token_span().start().to_u32(), 6); // global, not 0
    Status::Complete(())
})?;
Source

pub fn is_incomplete(&self, errors: &[Diagnostic]) -> bool

Returns true if errors say the input ended too soon rather than that it is wrong — the signal to ask for another line.

That is the case when there is at least one error-severity diagnostic, and every one of them points at the end of the input: its primary span starts at or after the last non-whitespace byte. A parser that reaches the end of 1 + (2 * reports “expected expression” at the end, so the user simply has not finished typing; a parser that trips over 1 + ) reports the error at the ), and more lines will never fix that. Warnings, notes, and help messages are ignored.

The rule matches how parser_lang reports a missing token at the end of input — an empty span just past the last token — and works with any parser that does the same. Errors a lexer reports where a construct starts, such as an unterminated string pointing at its opening quote, are not recognised; return Status::Incomplete for those directly.

§Examples
use diag_lang::{Diagnostic, Label, Severity};
use repl_lang::{Session, Span, Status};

let error_at = |at: u32| {
    Diagnostic::new(Severity::Error, "expected expression", Label::new(Span::empty(at), "here"))
};

let mut session = Session::new();
session.feed("1 + (2 *", |input| {
    // An error at the end (byte 8, before the trailing newline): incomplete.
    assert!(input.is_incomplete(&[error_at(8)]));
    // An error in the middle: the input is wrong, not unfinished.
    assert!(!input.is_incomplete(&[error_at(2), error_at(8)]));
    // No errors at all: complete.
    assert!(!input.is_incomplete(&[]));
    Status::Complete(())
})?;

Trait Implementations§

Source§

impl<'a> Clone for Input<'a>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Copy for Input<'a>

Source§

impl<'a> Debug for Input<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Eq for Input<'a>

Source§

impl<'a> PartialEq for Input<'a>

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<'a> StructuralPartialEq for Input<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Input<'a>

§

impl<'a> RefUnwindSafe for Input<'a>

§

impl<'a> Send for Input<'a>

§

impl<'a> Sync for Input<'a>

§

impl<'a> Unpin for Input<'a>

§

impl<'a> UnsafeUnpin for Input<'a>

§

impl<'a> UnwindSafe for Input<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.