Iterate over all declared constants in a crate

Background

  • I'd like to have a runtime function that can lookup any Win32 constant by name and return its value
  • The constants are defined in the windows-sys and its sister windows crates
  • I'm using this nice phf crate to generate (at build time) a static hashmap that provides for a fast lookup

Question:

How can I enumerate/iterate over all the thousands of declared constants like
pub const LOCALE_SENGCURRNAME: u32 = 4103u32;
in the windows crate at buld time to be able to store

  • the string LOCALE_SENGCURRNAME and
  • the value 4103u32

Thank you!

You don't. At least, not easily.

If you put a metaphorical gun to my head and told me I had to make this work, I can think of three possible avenues (in no particular order):

  1. I believe there's a way to use proc-macro2 to parse Rust source files. I'd feed that the appropriate source files extracted from windows-sys/windows and use it to generate a crate that, when compiled and run, would print out code that initialises the hash map. You can't just use the value directly because parsing won't give you types or values.

  2. rust-analyzer needs to be able to do this, so you could figure out how to point it at the crates and then query it for the necessary information. Again, use that to spit out Rust source for the hash map.

  3. The contents of the Windows binding crates (at least, the ones by Microsoft) are (at least partly) auto-generated from metadata files. You could get your hands on the metadata files, then modify the generator to spit out Rust code to make the hash map.

1 Like

Thanks for the tips for the laborious options that I wanted to avoid with some simple Rust reflection that doesn't seem to exist :slight_smile: , those constants are so close, yet also so far away...

  1. Does RA need to be able to get constant value as well or does it only need to know that a constant exists?
  2. I'm only aware of the GitHub - microsoft/win32metadata: Tooling to generate metadata for Win32 APIs in the Windows SDK. project that's supposed to be the source of the windows-sys crate, but don't know whether there is that generation connection which could be modified to spit out a hashmap item instead of a pub const rust code...

Rust doesn't have reflection, but there are cargo semver checks — a tool which may detect a situation where you have added some public constant and them if you removed it (that's obvious semver violation).

This tool obviously needs to get the information that you want/need. Maybe look on how it's implemented and what does it use to look on crates?

I think it calls rustc with some options to get that information.

1 Like

wouldn't it only need to know if a name is missing ("A pub const is missing, renamed, or changed to static." as this rule of theirs suggest) without requiring getting any value?

But maybe I could try to get the list of constants from that crate and then use some macro to iterate over the list to dynamically generate a real constant from the name to get its value from the acual imported windows-sys crate? :thinking:

Constant value is part of crate's API. And they are specified in docs, anyway. Tool, apparently, parses unstable rustdoc JSON output. Which may be good enough for your needs, if you don't need something that would be 100% supportable “forever”.

2 Likes

Just a quick update for future reference

Unfortunately not, the rustdocs don't contain values of various slightly more complicated types like

pub const Dot11AdHocManager        	:GUID 	= GUID::from_u128(0xdd06a84f_83bd_4d01_8ab9_2389fea0869e);
pub const IHV_INIT_VS_FUNCTION_NAME	:PCSTR	= s!("Dot11ExtIhvInitVirtualStation");

(which seems to be ~14k out of ~126k constants)

Unfortunately it (or rather the rustdocs plugin it used) didn't support constant values either. But at least the rustdocs plugin was patcheable unlike the rustdocs themselves that had info :frowning:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.