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

Allow nested_in to accept a parser that emits a different type of tokens #689

Open
TheOnlyTails opened this issue Oct 26, 2024 · 7 comments
Labels
api A problem with the design of an API feature help wanted Extra attention is needed

Comments

@TheOnlyTails
Copy link

I have this use case, where expr is a parser with (Token, Span) as the input, and the surrounding function returns a parser that takes in `(StringToken, Span)

expr.nested_in(select_ref! {
	StringToken::Interpolation(inner) = e => {
		inner.as_slice().spanned(SimpleSpan::to_end(&e.span()))
	},
});

However, this errors because nested_in expects the parser being passed in to both accept and return the same type, which clashes here.

@zesterer
Copy link
Owner

Hmm. I can see this use-case, certainly.

@zesterer zesterer added help wanted Extra attention is needed api A problem with the design of an API feature labels Oct 26, 2024
@TheOnlyTails
Copy link
Author

I think it's just a matter of changing around the type params to allow for it?

fn nested_in<IB: Input<'a>, EB: ParserExtra<'a, IB>, B: Parser<'a, IB, I, EB>>(
    self,
    other: B,
) -> NestedIn<Self, B, O, E>
where
    Self: Sized,
{
    NestedIn {
        parser_a: self,
        parser_b: other,
        phantom: EmptyPhantom::new(),
    }
}

@zesterer
Copy link
Owner

I've had a go at implementing this, and it does seem to work, but it comes with a constraint: specifically, that the State, Context, and Error types need to match between the inner and outer inputs.

I've pushed up a commit on main that makes this change. Could you give it a go to see if it does what you're looking for?

@TheOnlyTails
Copy link
Author

Updated, this seems to be related but I'm not sure how (maybe the same change needs to be made for select and select_ref?)

let interpolation= expr
	.nested_in::<_, StringInput, StringExtra>(select_ref! {
		StringToken::Interpolation(inner) = e => {
			inner.as_slice().spanned(SimpleSpan::to_end(&e.span()))
		},
	})
	.map(|t| StringPart::InterpolatedExpr(t.into()));
the method `map` exists for struct `NestedIn<P, SelectRef<{[email protected]:2809:13}, SpannedInput<..., ..., ...>, ..., ...>, ..., ..., ..., ...>`, but its trait bounds were not satisfied

@zesterer
Copy link
Owner

zesterer commented Oct 26, 2024

There's not enough information there to be useful. My hunch is that one of the constraints I listed is being violated somehow. If you have a small failing example I can run, that would be useful too.

@TheOnlyTails
Copy link
Author

Can we discuss on Discord or something? I don't want to clog up the issue tracker with debugging.

@zesterer
Copy link
Owner

Sure. I'm active on the Rust Community Discord, in the #langdev channel.

To anybody else reading this, any important information will be fed back here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api A problem with the design of an API feature help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants
@zesterer @TheOnlyTails and others