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  }