Skip to content

Commit 2b6d498

Browse files
committed
Simpler control actions when using GateState
1 parent 84b50e9 commit 2b6d498

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

Sources/GatedMiddleware/GatedMiddleware.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,4 +229,33 @@ extension Middleware {
229229
) -> GatedMiddleware<Self> {
230230
GatedMiddleware(middleware: self, controlActionMap: controlActionMap, turnOn: true, turnOff: false, default: gateState)
231231
}
232+
233+
/// Gated middleware is a middleware that holds an inner middleware that could be either active or not. The gated middleware has an internal state,
234+
/// called `gate state`, that determines whether or not the inner middleware should be in `active` or `bypass` mode. This can be changed dynamically.
235+
///
236+
/// Every gated middleware starts with an initial gate state, called "default gate state". From that point, it will evaluate all incoming actions to
237+
/// detect a "control action", which is an action for switching on or off the gate state. This control action is detected thanks to a control action
238+
/// map or a control map KeyPath configured in the GatedMiddleware's init, which from a given input action allows the user to inform either or not
239+
/// this is a control action returning an Optional instance of that ControlAction (or nil in case it's a regular action).
240+
///
241+
/// The init also requires some comparison values, for turnOn or turnOff the gate. If it's a control action, and it's equals to turn on, it will set
242+
/// the inner middleware to active. If it's a control action, and it's equals to turn off, it will set the inner middleware to bypass. If it's not a
243+
/// control action, or it's not equals to any of the comparison values, the gate will remain untouched.
244+
///
245+
/// There one last important topic. The gated middleware will ALWAYS forward control actions to inner middlewares, regardless of their gate state
246+
/// (active or bypass) and regardless of the turn on/turn off comparison result. This will allow important actions like disabling or enabling the
247+
/// inner middleware for control actions, so for example, even for when we close the gate we still want to tell the inner middleware that it's gonna
248+
/// be bypassed and it should kill all of its timers or async side-effects.
249+
/// - Parameters:
250+
/// - controlAction: a key-path that goes from incoming action to an optional `GateState`. It result is nil, it means this is not a control
251+
/// action. In case it has a non-nil `GateState`, this will enable (for `.active`) or bypass (for `.bypass`) the inner
252+
/// middleware. The inner middleware will also receive that control action regardless of its gate state.
253+
/// - gateState: initial `gateState`, either `active` or `bypass`
254+
/// - Returns: a `GatedMiddleware` containing internally this current middleware, allowing it to be bypassed or not.
255+
public func gated(
256+
controlActionMap: @escaping (InputActionType) -> GateState?,
257+
default gateState: GateState
258+
) -> GatedMiddleware<Self> {
259+
GatedMiddleware(middleware: self, controlActionMap: controlActionMap, turnOn: .active, turnOff: .bypass, default: gateState)
260+
}
232261
}

0 commit comments

Comments
 (0)