traefik/pkg/provider/kubernetes/ingress/convert.go
2023-04-03 10:06:06 +02:00

70 lines
1.5 KiB
Go

package ingress
import (
"errors"
corev1 "k8s.io/api/core/v1"
netv1 "k8s.io/api/networking/v1"
netv1beta1 "k8s.io/api/networking/v1beta1"
)
type marshaler interface {
Marshal() ([]byte, error)
}
type unmarshaler interface {
Unmarshal([]byte) error
}
type LoadBalancerIngress interface {
corev1.LoadBalancerIngress | netv1beta1.IngressLoadBalancerIngress | netv1.IngressLoadBalancerIngress
}
// convertSlice converts slice of LoadBalancerIngress to slice of LoadBalancerIngress.
// O (Bar), I (Foo) => []Bar.
func convertSlice[O LoadBalancerIngress, I LoadBalancerIngress](loadBalancerIngresses []I) ([]O, error) {
var results []O
for _, loadBalancerIngress := range loadBalancerIngresses {
mar, ok := any(&loadBalancerIngress).(marshaler)
if !ok {
// All the pointer of types related to the interface LoadBalancerIngress are compatible with the interface marshaler.
continue
}
um, err := convert[O](mar)
if err != nil {
return nil, err
}
v, ok := any(*um).(O)
if !ok {
continue
}
results = append(results, v)
}
return results, nil
}
// convert must only be used with unmarshaler and marshaler compatible types.
func convert[T any](input marshaler) (*T, error) {
data, err := input.Marshal()
if err != nil {
return nil, err
}
var output T
um, ok := any(&output).(unmarshaler)
if !ok {
return nil, errors.New("the output type doesn't implement unmarshaler interface")
}
err = um.Unmarshal(data)
if err != nil {
return nil, err
}
return &output, nil
}