Skip to content

Commit

Permalink
[pkg/ottl] Replace StandardTypeGetter with type-specific implementati…
Browse files Browse the repository at this point in the history
…ons (#22763)

* Replace StandardTypeGetter with type-specific instances

* changelog
  • Loading branch information
TylerHelmuth authored May 30, 2023
1 parent 62c39d6 commit 4014092
Show file tree
Hide file tree
Showing 16 changed files with 414 additions and 100 deletions.
20 changes: 20 additions & 0 deletions .chloggen/ottl-treat-primitive-and-pdata-the-same-2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Use this changelog template to create an entry for release notes.
# If your change doesn't affect end users, such as a test fix or a tooling change,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: breaking

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: pkg/ottl

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Removes `StandardTypeGetter` in favor of `StandardStringGetter`, `StandardIntGetter`, `StandardFloatGetter`, and `StandardPMapGetter`, which handle converting pcommon.Values of the proper type.

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [22763]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: This is only a breaking change for users using OTTL in custom components. For all Contrib components this is an enhancement.
105 changes: 96 additions & 9 deletions pkg/ottl/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,36 +139,123 @@ type StringGetter[K any] interface {
Get(ctx context.Context, tCtx K) (string, error)
}

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

func (g StandardStringGetter[K]) Get(ctx context.Context, tCtx K) (string, error) {
val, err := g.Getter(ctx, tCtx)
if err != nil {
return "", err
}
if val == nil {
return "", fmt.Errorf("expected string but got nil")
}
switch v := val.(type) {
case string:
return v, nil
case pcommon.Value:
if v.Type() == pcommon.ValueTypeStr {
return v.Str(), nil
}
return "", fmt.Errorf("expected string but got %v", v.Type())
default:
return "", fmt.Errorf("expected string but got %T", val)
}
}

type IntGetter[K any] interface {
Get(ctx context.Context, tCtx K) (int64, error)
}

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

func (g StandardIntGetter[K]) Get(ctx context.Context, tCtx K) (int64, error) {
val, err := g.Getter(ctx, tCtx)
if err != nil {
return 0, err
}
if val == nil {
return 0, fmt.Errorf("expected int64 but got nil")
}
switch v := val.(type) {
case int64:
return v, nil
case pcommon.Value:
if v.Type() == pcommon.ValueTypeInt {
return v.Int(), nil
}
return 0, fmt.Errorf("expected int64 but got %v", v.Type())
default:
return 0, fmt.Errorf("expected int64 but got %T", val)
}
}

type FloatGetter[K any] interface {
Get(ctx context.Context, tCtx K) (float64, error)
}

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

func (g StandardFloatGetter[K]) Get(ctx context.Context, tCtx K) (float64, error) {
val, err := g.Getter(ctx, tCtx)
if err != nil {
return 0, err
}
if val == nil {
return 0, fmt.Errorf("expected float64 but got nil")
}
switch v := val.(type) {
case float64:
return v, nil
case pcommon.Value:
if v.Type() == pcommon.ValueTypeDouble {
return v.Double(), nil
}
return 0, fmt.Errorf("expected float64 but got %v", v.Type())
default:
return 0, fmt.Errorf("expected float64 but got %T", val)
}
}

type PMapGetter[K any] interface {
Get(ctx context.Context, tCtx K) (pcommon.Map, error)
}

type StandardTypeGetter[K any, T any] struct {
type StandardPMapGetter[K any] struct {
Getter func(ctx context.Context, tCtx K) (interface{}, error)
}

func (g StandardTypeGetter[K, T]) Get(ctx context.Context, tCtx K) (T, error) {
var v T
func (g StandardPMapGetter[K]) Get(ctx context.Context, tCtx K) (pcommon.Map, error) {
val, err := g.Getter(ctx, tCtx)
if err != nil {
return v, err
return pcommon.Map{}, err
}
if val == nil {
return v, fmt.Errorf("expected %T but got nil", v)
return pcommon.Map{}, fmt.Errorf("expected pcommon.Map but got nil")
}
v, ok := val.(T)
if !ok {
return v, fmt.Errorf("expected %T but got %T", v, val)
switch v := val.(type) {
case pcommon.Map:
return v, nil
case pcommon.Value:
if v.Type() == pcommon.ValueTypeMap {
return v.Map(), nil
}
return pcommon.Map{}, fmt.Errorf("expected pcommon.Map but got %v", v.Type())
case map[string]any:
m := pcommon.NewMap()
err = m.FromRaw(v)
if err != nil {
return pcommon.Map{}, err
}
return m, nil
default:
return pcommon.Map{}, fmt.Errorf("expected pcommon.Map but got %T", val)
}
return v, nil
}

// StringLikeGetter is a Getter that returns a string by converting the underlying value to a string if necessary.
Expand Down
Loading

0 comments on commit 4014092

Please sign in to comment.