-
Notifications
You must be signed in to change notification settings - Fork 734
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
subscriber: add
Targets::targets
method to iterate directives (#1574)
There's currently no way to get the registered directives from a `Targets` instance, which is a barrier to some use-cases such as combining user-supplied directives with application-supplied defaults. This commit adds a `Targets::targets` method, which returns an iterator of `(&str, LevelFilter)` pairs, one for each directive (excluding the default level, whose `target` is `None`). Items are yielded as per the underlying `DirectiveSet::directives`, which would yield itms in specifity order (as constructed by `DirectiveSet::add`). However, the order has been left explicitly undefined in the documentation for `Targets::targets` on the basis that this is an implementation detail that may change. ## Motivation As hinted in the commit message, my use-case is to have an application-supplied 'base' `Targets` filter, which can then be extended/overridden by a user-supplied filter parsed from `RUST_LOG` (e.g.). Sadly, there's currently no way of getting the directives out of a `Targets` instance, nor to re-serialize to the string representation. Thus, the only way to implement the above would be to manually parse the user-supplied filters in the application, which is shame since it duplicates the implementation here and would be prone to drift/subtle incompatibilities. ## Solution The proposed solution is to add methods to `Targets` to retrieve the underlying directives. ```rust // application-defined defaults, for a useful level of information let mut filter = Targets::new() .with_target("my_crate", LevelFilter::INFO) .with_target("important_dependency", LevelFilter::INFO); if let Ok(overrides) = std::env::var("RUST_LOG") { let overrides: Targets = overrides.parse().unwrap(); // merge user-supplied overrides, which can enable additional tracing // or disable default tracing filter.extend(overrides.iter()); // ^^^^^^^^^ this is new } ``` For this PR, I've gone for `fn iter(&self) -> Iter`, e.g. a method `targets` that returns an iterator over the pairs of `(&str, LevelFilter)` in the underlying directives. The iterator excludes any default level(s) where `target` would be `None`. This matches nicely with the `FromIterator` and `Extend` impls, which use `(impl Into<String>, impl Into<LevelFilter>)`. In addition, I've added `IntoIterator` implementations for `&Targets` and for `Targets`. The by-value `IntoIterator` implementation returns an `IntoIter` type that moves the targets as `String`s, rather than as borrowed `&str`s. This makes `extend` more efficient when moving a second `Targets` by value.
- Loading branch information
1 parent
133be44
commit 4ba4485
Showing
3 changed files
with
206 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters