Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to peek for EOF? #1161

Closed
ModProg opened this issue Apr 19, 2022 · 3 comments
Closed

Is it possible to peek for EOF? #1161

ModProg opened this issue Apr 19, 2022 · 3 comments

Comments

@ModProg
Copy link
Contributor

ModProg commented Apr 19, 2022

I need to check if I'm at the end of the input or in front of some delimiter, to parse in a certain way. Checking for the delimiter works perfectly with peek2 but I cannot check if I'm at the end of the input with peeking.

@dtolnay
Copy link
Owner

dtolnay commented Jan 23, 2023

#889 describes some ways to accomplish this.

@dtolnay dtolnay closed this as completed Jan 23, 2023
@ModProg
Copy link
Contributor Author

ModProg commented Nov 3, 2023

For anyone stumbling on this and looking for something that does not require forking everytime one wants to peek if the token is the last one, I found that there is a way to define ones own Eof token:

#[derive(Clone, Copy, Debug, Default)]
struct Eof {}

impl syn::token::CustomToken for Eof {
    fn peek(cursor: syn::buffer::Cursor) -> bool {
        cursor.eof()
    }

    fn display() -> &'static str {
        "EOF"
    }
}

#[allow(non_snake_case)]
fn Eof(_: impl syn::__private::IntoSpans<Span>) -> Eof {
    Eof {}
}

// usage
input.peek2(Eof);

note though that this uses the IntoSpans trait which is inside __private and CustomToken which is #[doc(hidden)] and which probably do not have any stability guarantees. So tread carefully.

@ModProg
Copy link
Contributor Author

ModProg commented Mar 23, 2024

The solution I proposed doesn not seem to work anymore (shouldn't use hidden API I guess), alternative is to create a helper function that just steps a bit to check for eof:

fn peek2_eof(input: ParseStream) -> bool {
    let mut ts = input.fork().parse::<TokenStream>().unwrap().into_iter();
    ts.next();
    ts.next().is_none()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants