Merged
Conversation
This reverts commit e22aa5f.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR brings several improvements to the CGP getters, making them more usable for more advanced uses.
MapFieldA new blanket trait
MapFieldhas been introduced to help with type inference when chaining field accessors:The general problem is as follows: when a field value is used as an intermediary to get an inner value, Rust would fail to infer the lifetime of the intermediary value, and thus requiring it to have a
'staticlifetime.For example, a generic implementation of
context.get_field(PhantomData::<symbol!("foo")>).get_field(PhantomData::<symbol!("bar")>)would require<Context as HasField<symbol!("foo")>>::Value: 'static. However, withMapField, we can rewrite the expression ascontext.map_field(PhantomData::<symbol!("foo")>, |inner| inner.get_field(PhantomData::<symbol!("bar")>)), and the lifetime inference will be fixed.Relaxed
HasFieldimplementation forDerefThe
HasFieldtrait has a blanket implementation for context types that implementDeref. Previously, the blanket implementation requiredTarget: 'staticdue to the same lifetime issues mentioned earlier.By introducing a
DerefMaphelper trait similar toMapField, we have managed to remove the'staticbound, and allows the blanket implementation to also work on types that contain non-static lifetimes.Auto infer provider name in
#[cgp_getter]Previously, at minimal the provider name must always be specified when defining getter traits using
#[cgp_getter]. For example:This requirement has been relaxed if the getter trait name follows the convention
Has{FieldName}. In such cases, the provider name is automatically set to{FieldName}Getter. So the same example can be simplified to:Note that if the getter trait name does not start with "Has", then a provider name must still be explicitly specified.
ChainGettersA new
ChainGettersprovider has been implemented to allow chaining nested getters together to form a singleFieldGetter. The implementation makes use ofMapFieldto overcome the lifetime errors, that would have required the intermediary value type to be'static. This can be useful for implementing chain getters for values nested within the sub-fields of a context.Following is an example context where the
listen_portfield is nested within sub-config types:Note that since
ChainGettersis a non-standardFieldGetterimplementation, it can only be used by#[cgp_getter]traits through theWithProviderwrapper provider.