I am currently trying to write a binary crate as a wrapper for a library, which sets constants based on feature flags that feature flag set of the package taking it as a dependency.
My initial thought was to create three intermediary packages for each of the feature flags, and then call those, however, I now understand that these features are additive, and so it will simply set the constant to be whichever cfg! statement evaluates first.
My question is therefore, is there a way to compile this shared dependency three times for each of the intermediary packages, therefore only setting one of the features at a time? Or, is there another way to get around this?
There is no way to duplicate a dependency without making a copy of the source code and declaring it to be a different package.
It sounds like the library is misusing features for a configuration that would be better suited for a function parameter (or const generic, if it really needs to be constant). I say this not just because it is not working for you, but because it is failing to have additive features. "Additive" isn't referring to how Cargo combines feature sets, but to the idea that activating a feature should never remove functionality that was present without it (in this case, operating with a different value for the constant than that feature requests).
The best path forward would be to patch the library to use const generics or regular function parameters.
Thanks for your response, that does make a lot of sense, and reinforces what I was lead to believe from my own reading around.
I'm trying to wrap my head around how it should be done in a rust way, but struggling to understand how it would work. To give a bit more detail, the features are used to determine a security level, which then influences other constants - moving these to parameters or const generics would mean that (nearly) every function would need an extra 10-11 parameters.
I have thought about perhaps using structs, but I don't believe that structs support constant values (due to the nature of the values I believe it best to keep them as constants), but can't think of any alternatives.
If one "security level" sets all the other parameters, those can be expressed as const fns that take the security level as an argument and compute the derived information. So, only the security level need be passed around, whether as a const generic or a regular function argument.
Thanks for the answers everyone! Still fairly new to rust, so enjoying these new ways of thinking about everything. In the end, I have made changes so that it'll be:
constants for true constants
struct containing security level variables
struct methods to get other parameters that depend on security level variables
So far, I believe that this is the most elegant, readable and consistant approach, but of course, if there is anything glaringly obviously wrong with how I have done this then please let me know