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
Option to put generated context selectors into a submodule #188
Comments
Yes, I think such an option does make sense. I expect that most people who have run into the problem have done as you suggest: put it in a module "by hand" and perform the relevant exports. I think that your general sketch of the resulting code also is the good default when this is opted-in-to: create a module (name chosen by user), put all the context selectors in that module, then mark them as There will undoubtedly be some nuances that are run into during development, but this seems like it's in a good state to start work on. Would you be interested in taking a crack at it? |
i actually wanted to suggest the same thing, main difference i would prefer is it to be named something like |
@shepmaster Sorry I haven't gotten back sooner! I'm interested in helping build this, but after using SNAFU in more projects I wonder if it's the right solution to the name-collision problem. Does it make sense for SNAFU to generate the context selectors with a name that doesn't match the enum variants directly? Could we introduce an enum-variant attribute to change the generated selector name? SNAFU could automatically name your selectors in a way that isn't your enum variant verbatim (which would obviously be a breaking change), SNAFU could name the selector For manual names, it could be reasonable to let the user specify: use crate::{Config, ConfigError};
#[derive(Debug, Snafu)]
pub enum SyncError {
#[snafu(selector = ConfigContext)]
Config {
source: ConfigError,
}
}
pub fn sync() -> Result<(), SyncError> {
let config = Config::load().context(ConfigContext)?; // All good now!
// ...
} This is a smaller hammer than namespacing all the context selectors. Alternatively, we could implement this feature as proposed, and then encourage users to then re-export their selectors. That would look like this: use crate::{Config, ConfigError};
#[derive(Debug, Snafu)]
#[snafu(mod = "error")]
pub enum SyncError {
Config {
source: ConfigError,
}
}
// We can't glob-import the context selectors if we need to rename any of them.
use error::Config as ConfigContext;
pub fn sync() -> Result<(), SyncError> {
let config = Config::load().context(ConfigContext)?; // All good now!
// ...
} |
The new attribute `module` makes the derive macro put all the context selectors for structs and enums in a module.
The new attribute `module` makes the derive macro put all the context selectors for structs and enums in a module.
The new attribute `module` makes the derive macro put all the context selectors for structs and enums in a module.
The new attribute `module` makes the derive macro put all the context selectors for structs and enums in a module. Closes shepmaster#188
The new attribute `module` makes the derive macro put all the context selectors for structs and enums in a module. Closes shepmaster#188
The new attribute `module` makes the derive macro put all the context selectors for structs and enums in a module. Closes shepmaster#188
The new attribute `module` makes the derive macro put all the context selectors for structs and enums in a module. Closes shepmaster#188
The new attribute `module` makes the derive macro put all the context selectors for structs and enums in a module. Closes shepmaster#188
First, thanks for making SNAFU, I'm really enjoying its ergonomics!
I started a new project and tried to create a couple nested errors, but hit a name collision between the selectors that SNAFU was generating and one of my existing structs.
My inner module looks like this:
My outer module imports a couple things from this struct and exports a new error type that wraps
ConfigError
:The
Snafu
derive macro onSyncError
tries to define a struct namedConfig
as the context selector, which ends up colliding with the structConfig
that I imported before!One solution for this particular case I thought of was to put my SNAFU error into its own
mod
block to scope everything the macro defines. Combined with#[snafu(visibility)]
and re-exporting the error type, this seems to work:Another way we could solve this is by adding a configuration option like
#[snafu(mod = "error")]
to instruct SNAFU to wrap all of its context selectors into a module with the given name.Does this feature make sense? Is there a better solution to this particular problem that I'm not seeing?
Thanks!
The text was updated successfully, but these errors were encountered: