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

Possible to add value_as_str? #15

Closed
eugenesvk opened this issue Oct 8, 2023 · 5 comments
Closed

Possible to add value_as_str? #15

eugenesvk opened this issue Oct 8, 2023 · 5 comments

Comments

@eugenesvk
Copy link

If you have various primitive types in a string form from rustdocs (like 5_000i32 etc) and want to extract the 5000 without any _ (for this case a string output is fine), you can parse the strings with

pub fn value<N: FromIntegerLiteral>(&self) -> Option

But then this ignores the existing suffix

The optional type suffix of the literal is ignored by this method.

so it requires matching for all the valid suffixes to get the type N (and account for the weird fact that f32 isn't a float, but an integer, so you shouln't forget that suffix in the integers)

The alternative to get the string directly...

pub fn raw_main_part(&self) -> &str
...ignores the base

The main part containing the digits and potentially _. Do not try to parse this directly as that would ignore the base!

Would it be possible to add a function that would allow extracting the number accounting for the base and not requiring enumerating all the suffixes?

@LukasKalbertodt
Copy link
Owner

Instead of matching all different suffixes, you can just call lit.value::<u128>().map(|n| n.to_string()). I.e. you can just use the largest integer type to deal with all values. Also remember that there are no negative literals, so it actually can represent all possible integer literal values. (Well, the Rust grammar allows arbitrarily large integers in the lexicographical grammar, but it still disallows integers larger than u128 in a later stage.)

Is that what you are looking for? Would you still say that functionality should be added as function? I will probably add some docs about the "largest integer trick".

@eugenesvk
Copy link
Author

Also remember that there are no negative literals, so it actually can represent all possible integer literal values

Thanks for the reminder, I got hit by exactly this after opening the issue, and fixed it by going with the trick you later mentioned (weirdly, I already had u128 in the _ arm, but for some reason though it'd be better to stick to the "correct" types).

Would you still say that functionality should be added as function?

Yes, I think the user should not need to learn about these Rust grammar quirks, and also think number is an important part for it be easily extracted just like other chunks like base.
So hopefully with the added lenient parser mentioned #14 this would become a reality

@LukasKalbertodt
Copy link
Owner

Can you quickly explain what you will do with that resulting string? How are you using that?

@eugenesvk
Copy link
Author

eugenesvk commented Oct 9, 2023

Sure. I store the result in a key-value database so that I can retrieve it later in a script (and use it as an embedded database in a dll). The original strings are win32 API constant values that I get from parsing rustdocs for a Windows sys crate (which seems like the easiest way to get them). I use your crate to then convert those string constant values to a "clean" non-suffixed-non-_ number

So ideally I'd have a single and simple Literal::parse_lenient(const_str).value_str() call (and get the number part for numbers, and string for char/string etc) and call it a day :). Not having to handle minus signs and types gets very close to this

(in a potentially better future I might need to retain the numeric types instead of using strings, that's where the no-sign parsing will bite again and require separate handling in addition to separate matching, but that's a different issue)

LukasKalbertodt added a commit that referenced this issue Oct 18, 2023
@LukasKalbertodt
Copy link
Owner

I've thought about this whole lenient idea again and I decided that litrs is not the right place for that. There are many different useful things one could offer (parsing integers as floats, accepting minus signs, and plus signs, ...). That easily could run into the feature creep problem. I prefer this crate to be very focused on just spec-compliant parsing of literals.

I also decided against value_as_str, since it would just be lit.value::<u128>().to_string() and seems a bit too specialized to me to provide a method for this pair of method calls. Instead, I added a hint to the docs, which helps hopefully.

I do agree though that these features are very useful to have generally. I just think they should live in a different crate. I might even build one as I have use for it as well (e.g. in confique). But no promises and don't hold your breath.

Sorry for the probably disappointing outcome!

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