Skip to content
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

Replace "Functions" return type from ExprFunc to interface/struct #14713

Closed
bogdandrutu opened this issue Oct 4, 2022 · 4 comments · Fixed by #15709
Closed

Replace "Functions" return type from ExprFunc to interface/struct #14713

bogdandrutu opened this issue Oct 4, 2022 · 4 comments · Fixed by #15709
Labels
enhancement New feature or request pkg/ottl priority:p2 Medium

Comments

@bogdandrutu
Copy link
Member

Describe the issue you're reporting

Currently ExprFunc is a concrete type type ExprFunc[K any] func(ctx K) interface{}. This does not allow us to extend the functionality in the future (as defined currently). Proposal is to replace this with an interface or a struct that allows us to extend the functionality/capabilities in the future.

If we use interface we can define optional interfaces in the future that we can extend. If we use a struct, we can add more members or extend that. Here is the struct example:

type ExprFunc[K any] func(K) interface{}

func (f ExprFunc) Exec(ctx K) {
  f(ctx)
}

type Expr struct {
   ExprFunc
   // In the future we can add more members that have different capabilities/options to this.
}
@TylerHelmuth
Copy link
Member

TylerHelmuth commented Oct 25, 2022

@bogdandrutu in this situation

type Expr[K any] struct {
  ExprFunc[K]
}

func (e Expr[K]) Eval(ctx context.Context, tCtx K) {
  return e.ExprFunc(ctx, tCtx)
}

type ExprFunc[K any] func(ctx context.Context, tCtx K) (interface{}, error)

can't we get away without the Eval function and instead do

var x Expr[K]
x.ExprFunc(...)

If Eval is providing something that I'm missing I'd prefer to unexport ExprFunc so that users can't see both Eval and ExprFunc on the Expr[K] struct.

Unxporting ExprFunc means functions need to create an Expr[K] via a New function. If the only field on the Expr[K] struct is ever going to be an ExprFunc, then we could do.

func NewExpr[K any](f exprFunc[K]) Expr[K] {
	return Expr[K]{f}
}

func Concat[K any](vals []ottl.Getter[K], delimiter string) (ottl.Expr[K], error) {
	return ottl.NewExpr[K](func(ctx context.Context, tCtx K) interface{} {
		builder := strings.Builder{}
		for i, rv := range vals {
			switch val := rv.Get(ctx, tCtx).(type) {
			case string:
				builder.WriteString(val)
			case []byte:
				builder.WriteString(fmt.Sprintf("%x", val))
			case int64:
				builder.WriteString(fmt.Sprint(val))
			case float64:
				builder.WriteString(fmt.Sprint(val))
			case bool:
				builder.WriteString(fmt.Sprint(val))
			case nil:
				builder.WriteString(fmt.Sprint(val))
			}

			if i != len(vals)-1 {
				builder.WriteString(delimiter)
			}
		}
		return builder.String()
	}), nil
}

@bogdandrutu
Copy link
Member Author

Can you summarize the proposal in one comment, hard to follow :)

@TylerHelmuth
Copy link
Member

@bogdandrutu summarized.

@TylerHelmuth
Copy link
Member

TylerHelmuth commented Oct 28, 2022

Ended up going with a simpler approach that my above comments. opening PR shortly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request pkg/ottl priority:p2 Medium
Projects
None yet
3 participants