go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/async/interceptors.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package async 9 10 // Interceptors chains calls to interceptors as a single interceptor. 11 func Interceptors[T, V any](interceptors ...Interceptor[T, V]) Interceptor[T, V] { 12 if len(interceptors) == 0 { 13 return nil 14 } 15 if len(interceptors) == 1 { 16 return interceptors[0] 17 } 18 19 var curry = func(a, b Interceptor[T, V]) Interceptor[T, V] { 20 if a == nil && b == nil { 21 return nil 22 } 23 if a == nil { 24 return b 25 } 26 if b == nil { 27 return a 28 } 29 return InterceptorFunc[T, V](func(i Actioner[T, V]) Actioner[T, V] { 30 return b.Intercept(a.Intercept(i)) 31 }) 32 } 33 interceptor := interceptors[0] 34 for _, next := range interceptors[1:] { 35 interceptor = curry(interceptor, next) 36 } 37 return interceptor 38 } 39 40 // Interceptor returns an actioner for a given actioner. 41 type Interceptor[T, V any] interface { 42 Intercept(action Actioner[T, V]) Actioner[T, V] 43 } 44 45 var ( 46 _ Interceptor[int, int] = (*InterceptorFunc[int, int])(nil) 47 ) 48 49 // InterceptorFunc is a function that implements action. 50 type InterceptorFunc[T, V any] func(Actioner[T, V]) Actioner[T, V] 51 52 // Intercept implements Interceptor for the function. 53 func (fn InterceptorFunc[T, V]) Intercept(action Actioner[T, V]) Actioner[T, V] { 54 return fn(action) 55 }