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

Find a different syntax for inline snapshot so that cargo fmt can work #499

Open
tisonkun opened this issue Jun 8, 2024 · 8 comments
Open

Comments

@tisonkun
Copy link
Contributor

tisonkun commented Jun 8, 2024

Currently, @r###"..."### the inline snapshot syntax is invalid during cargo fmt analyze and cannot be formatted.

Perhaps a different syntax (e.g. i=r"") can be used for helping in this case.

@max-sixty
Copy link
Collaborator

Check out #456, both this:

Would be great for inline snapshots to work with rustfmt, but don't think there's a way — if the inline snapshot is a normal expression without special syntax (such as @), it's not possible to discriminate between (name, value) and (value, snapshot)

...and the broader discussion.

I agree that it would be great to allow rustfmt to work, though lots of other tradeoffs...

@andylokandy
Copy link

andylokandy commented Sep 22, 2024

Sharing my workaround:

  1. Before cargo fmt, run sg scan --rule <path to yaml> (need to install ast-grep)
# Replace `@` with `-` in macros
id: pre-format
language: Rust
rule:
  pattern: '@'
  precedes:
    kind: raw_string_literal
  inside:
    kind: macro_invocation
    stopBy: end
fix: '-'
  1. Run cargo fmt

  2. Finally, run sg scan --rule <path to yaml>

# Replace `-` with `@` in macros
id: post-format
language: Rust
rule:
  pattern: '-'
  precedes:
    kind: raw_string_literal
  inside:
    kind: macro_invocation
    stopBy: end
fix: '@'

@max-sixty
Copy link
Collaborator

max-sixty commented Sep 22, 2024

from #605 (comment)

rustfmt is requiring a syntactical valid expression, but not semantically valid expression. Thus there is room to find such patterns. For example, my using -r###""### utilize the fact that unary minus to a string is valid in syntax but invalid in type. Symbols like *, !, ?(postfix) are also possible.

OK, that's quite interesting.

@max-sixty
Copy link
Collaborator

max-sixty commented Sep 22, 2024

@andylokandy, on further reflection, I'm not sure there's a syntax which would actually work here?

We need to identify the type of macro in the macro_rules!. Currently we do that with @literal and:

  • If we use something syntactically valid like !"Testing", then the macro has ambiguities
  • If we use something like +"Testing", then cargo fmt no longer works

Am I right in thinking this is the full set of options? Or is there some other way around it?

Here's a WIP branch with me trying things (originally tried +, then tried !...): https://github.com/max-sixty/insta/tree/plus

@andylokandy
Copy link

If we use something syntactically valid like !"Testing", then the macro has ambiguities

Could you provide a example of the ambiguities? I may not fully understand it. (and what if *?)

@max-sixty
Copy link
Collaborator

Try my branch — the rust compiler will complain about ambiguities in the macro...

@andylokandy
Copy link

Got it. It's a limitation of the compiler (lack of backtrack when parsing macro), but there is a nasty way to get through: instead of directly defining the pattern arms, consume the tokens one by one. In detail:

  1. receive input as $($input:tt)*
  2. match one token a time, until the pattern is determined
  3. call sub-macro for each pattern

Here is a demo of this technique.

@max-sixty
Copy link
Collaborator

Ah OK cool!

If you want to make a branch / draft PR with this on, I think that would be quite helpful. Assuming the interface for users is still nice and internal stuff is well-documented, I would be +1 on this.

(...though I'm not the sole decider, to set expectations)

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

3 participants