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

[1.0.0] Set cannot be called as inner value of Data Structures (macro edn!) #4

Open
naomijub opened this issue Jan 1, 2020 · 3 comments
Labels
bug Something isn't working help wanted Extra attention is needed parse Set
Milestone

Comments

@naomijub
Copy link
Collaborator

naomijub commented Jan 1, 2020

The macro edn! fails when we try to call a Set inside any other structure.

edn!([ 1 2 3 #{4 5 6}])

Gets an error of expected [, found end of macro arguments. Same is valid for set in set, #{ 1 2 3 #{4 5 6}}.

@naomijub naomijub added bug Something isn't working serde Set labels Jan 1, 2020
@naomijub naomijub changed the title Set cannot be called as inner value of Data Structures Set cannot be called as inner value of Data Structures (macro edn!) Jul 15, 2020
@naomijub naomijub added parse and removed serde labels Aug 27, 2020
@naomijub naomijub added hacktoberfest-accepted help wanted Extra attention is needed labels Oct 21, 2020
@naomijub naomijub changed the title Set cannot be called as inner value of Data Structures (macro edn!) [1.0.0] Set cannot be called as inner value of Data Structures (macro edn!) Nov 14, 2020
@Grinkers Grinkers added this to the 1.0.0 milestone Nov 24, 2023
@Grinkers
Copy link
Member

Grinkers commented Feb 24, 2024

What is the use case for the edn! macro? I wasn't really thinking about it until looking closely at the README. In several places it is called "parse", but it's not really parsing; it is compile-time generation of Edn objects. Pretty neat to quickly hard-code some EDN. I'm guessing this was a common thing for the original use case of this crate? It's right on the top of the README.

Doing it like this has a lot of limitations, like this issue. This seems like an almost impossible (or at least an endless) task or it quickly reinventing all of proc_macro, syn, quote, and edn-rs.

I finally got around to learning about proc_macros this weekend. I made a proof of concept. This is not done yet. I wanted opinions before going through and doing the rest, testing it, etc. This needs to be a separate crate because it's a proc-macro lib. This macro will handle any valid EDN, because it uses this crate's parse, at compile time.

You can see the minimal example, with this issue's original EDN here
https://github.com/Grinkers/constexpr_edn/blob/main/examples/example.rs

Eventually rust's const will be as powerful as c++'s constexpr, which should actually allow this crate's parse to also be const. That would make this macro and my proof of concept crate no longer needed.

@naomijub Any thoughts on just removing the macro entirely from this crate and having a macro crate until parse can be const?

@Grinkers
Copy link
Member

Grinkers commented Feb 25, 2024

I made it match the current usage a bit more. I also managed to make it dependency-free. If we go this route, I'll go for 100% coverage and move over all existing tests. It seems to work with all the insanity you would expect from valid EDN
https://github.com/Grinkers/constexpr_edn/blob/main/examples/example.rs#L18

A side note, doing it this way actually gives some nice compiler warnings. For example, using my "parse" branch

let edn = edn!([42, "foobar" yaycats 42r1001]);
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: message: called `Result::unwrap()` on an `Err` value: EdnError { code: InvalidRadix(Some(42)), line: Some(1), column: Some(23), ptr: Some(22) }

@Grinkers
Copy link
Member

Grinkers commented Feb 25, 2024

Depending on what we do with #148 we can actually capture with a proc_macro
https://github.com/Grinkers/constexpr_edn/blob/ba130aaaca55fb4df19b4826b6782c763ad713c3/examples/example.rs#L28-L31

so it should be possible to do something like

let num = some_calc();
return edn!({:ok "ok" :num #capt num}); 

or maybe there's some other symbols we can use, like
edn!({:ok "ok" :num %num%}). brackets is already used in edn, so whatever it ends up being, it won't be rust-like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed parse Set
Projects
None yet
Development

No branches or pull requests

2 participants