winnow-rs / winnow

Making parsing a breeze
https://docs.rs/winnow
Other
573 stars 46 forks source link

Lazy context #605

Open 9999years opened 1 month ago

9999years commented 1 month ago

Please complete the following tasks

winnow version

master

Describe your use case

I'd like to add context to parsers without immediately allocating a Vec for them

Describe the solution you'd like

Would it be possible to have a .context_from(|| vec!["context1", "context2"]) function which only computes the context on error branches? Ideally this would be a middle-ground for performance between allocating the contexts up-front and omitting them entirely.

Alternatives, if applicable

Not sure! I'm interested to hear discussion.

Additional Context

See #421.

epage commented 1 month ago

Could you share your error type and context type?

9999years commented 1 month ago

I'm using PResult<ContextError<StrContext>>, but I'll probably create my own context type like this so I can dynamically construct informative parse context messages:

#[derive(Debug, Clone)]
pub enum ParseContext {
    Description(Cow<'static, str>),
    Expected(Cow<'static, str>),
}
epage commented 1 month ago

ContextError doesn't immediately allocate but does only pushes on error.

I'm confused by the example because you don't pass a Vec to context but a single context.

9999years commented 1 month ago

I'm confused by the example because you don't pass a Vec to context but a single context.

Yeah, sorry, to be clear I mean a method which computes multiple contexts up-front.

ContextError doesn't immediately allocate but does only pushes on error.

You're right, thank you. I've looked at the code a bit more. But the Parser::context method does take the context up-front, which means that the cost of computing the context itself is always paid. Not much of an issue for &'static str contexts, but for anything else it could be expensive:

https://github.com/winnow-rs/winnow/blob/8674ed2c3f57963a4e96c56616ee0a35f58cd258/src/parser.rs#L646-L660

Maybe I'm just holding it wrong? Not sure.

epage commented 1 month ago

It would help if you gave a more complete example of what you are trying to accomplish.