-
Notifications
You must be signed in to change notification settings - Fork 14
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
Add 'Interceptions' class with Builder #105
Conversation
For the most part it looks good to me, I just had one question about your decision to move the Interception convenience functions ( As for your note on the Because I liked the looks of: buildInterceptions<PasswordResetState, PasswordResetAction> {
named("Block duplicate requests if one is 'Incomplete'")
addFilterOn<ResendResetPassword> { state, _ ->
state.resetEmailStatus !is Incomplete
}
named("Adapt 'Resend' to 'Reset' password")
addAdapterOn<ResendResetPassword> { state, _ ->
ResetPassword(state.email, true)
}
named("Block duplicate resets")
addFilterOn<ResetPassword> { state, action ->
!state.hasInitialized || action.isResend
}
named("Call server to reset password")
addLiveCommandOn<ResetPassword> { _, action ->
resetPasswordUseCase(this, action.email) { PasswordResetAction.UpdateResetStatus(it) }
}
} Over: buildInterceptions<PasswordResetState, PasswordResetAction> {
named("Block duplicate requests if one is 'Incomplete'")
addFilter { state, action ->
if (action is ResendResetPassword) state.resetEmailStatus !is Incomplete
else true
}
named("Adapt 'Resend' to 'Reset' password")
addAdapter { state, action ->
if (action is ResendResetPassword) ResetPassword(state.email, true)
else action
}
named("Block duplicate resets")
addFilter { state, action ->
if (action is ResetPassword) !state.hasInitialized || action.isResend
else true
}
named("Call server to reset password")
addLiveCommand { action ->
when (action) {
is ResetPassword -> forwarding {
resetPasswordUseCase(this, action.email) {result ->
PasswordResetAction.UpdateResetStatus(result)
}
}
else -> ignoring()
}
}
} It makes it less verbose, which I think pairs well with the DSL mentality. (Ignore the I was also toying with the idea of having something like: buildInterceptions<PasswordResetState, PasswordResetAction> {
on<ResendResetPassword> {
named("Block duplicate requests if one is 'Incomplete'")
addFilter { state, _ -> state.resetEmailStatus !is Incomplete }
named("Adapt 'Resend' to 'Reset' password")
addAdapter { state, _ -> ResetPassword(state.email, true) }
}
on<ResetPassword> {
named("Block duplicate resets")
addFilterOn<ResetPassword> { state, action -> !state.hasInitialized || action.isResend }
named("Call server to reset password")
addLiveCommandOn<ResetPassword> { _, action ->
resetPasswordUseCase(this, action.email) { UpdateResetStatus(it) }
}
}
} As I frequently seem to have multiple So with my current use-case, I can get by with most of your builder, but the targeted |
You make some very good points. 🙂 I'll think about it and will make some refinements. |
521a1cf
to
9533a91
Compare
9533a91
to
e9346fa
Compare
@jordond I made some adjustments. I changed all interceptions to final classes that expect constructor parameters instead of overriding functions. I think that'll make the library easier to understand and work with: val sampleAdapter = Adapter<SampleState, SampleAction> { state, action ->
if (state.that && action is SampleAction.DoSomething) SampleAction.DoThat else action
} I also added interceptions<SampleState, SampleAction> {
pipe { _, action -> Log.d("Sample", "Chain result: $action") }
on<SampleAction.DoSomething> {
adapter { state, action -> if (state.that) SampleAction.DoThat else action }
filter { state, _ -> !state.doingSomething }
}
} The interceptions<SampleState, SampleAction> {
pipe("Log chain result") { _, action -> Log.d("Sample", "Chain result: $action") }
...
} I also toyed with some alternatives like your Let me know what you think. 🙂 |
Nice! It's looking great, I love the |
Resolves #104.
@jordond Could you maybe take a look and check if this implementation would fit your needs? I tried to match some of your proposals while also allowing easy building with testable Interceptions and integrating it with
EiffelViewModel
.It now allows composing the interceptions chain in three different ways.
Providing a list of
Interception
instances:Using the
Interceptions.Builder
class:Using the DSL-like wrapper for the builder class:
Interceptions
implements theList<E>
interface by delegating to its chain soEiffelViewModel
can still use it just as before.I omitted your "on" style statements for now since I think it would make more sense to provide a full DSL for declaratively creating interceptions in the future. Something like this would be nice:
But that will probably require a lot more work and consideration.