Skip to content

Commit

Permalink
Added changes from flyteplugins and also added functionality for Fetc…
Browse files Browse the repository at this point in the history
…hFromLiteral (#101)

* Added changes from flyteplugins

* Moved more code fromflyteplugins due to test dependencies

* Moved unit test for time primitive

* Added fetchFromliteral functionality

* Fixing lint issues

* Minor lint fixes

* Moved Fetch literal functionality to separate file

* Incorporated the feedback

Co-authored-by: pmahindrakar <[email protected]>
  • Loading branch information
pmahindrakar-oss and pmahindrakar authored Feb 23, 2021
1 parent b0e16d1 commit 12df6de
Show file tree
Hide file tree
Showing 6 changed files with 570 additions and 23 deletions.
81 changes: 81 additions & 0 deletions flyteidl/clients/go/coreutils/extract_literal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// extract_literal.go
// Utility methods to extract a native golang value from a given Literal.
// Usage:
// 1] string literal extraction
// lit, _ := MakeLiteral("test_string")
// val, _ := ExtractFromLiteral(lit)
// 2] integer literal extraction. integer would be extracted in type int64.
// lit, _ := MakeLiteral([]interface{}{1, 2, 3})
// val, _ := ExtractFromLiteral(lit)
// 3] float literal extraction. float would be extracted in type float64.
// lit, _ := MakeLiteral([]interface{}{1.0, 2.0, 3.0})
// val, _ := ExtractFromLiteral(lit)
// 4] map of boolean literal extraction.
// mapInstance := map[string]interface{}{
// "key1": []interface{}{1, 2, 3},
// "key2": []interface{}{5},
// }
// lit, _ := MakeLiteral(mapInstance)
// val, _ := ExtractFromLiteral(lit)
// For further examples check the test TestFetchLiteral in extract_literal_test.go

package coreutils

import (
"fmt"

"github.com/lyft/flyteidl/gen/pb-go/flyteidl/core"
)

func ExtractFromLiteral(literal *core.Literal) (interface{}, error) {
switch literalValue := literal.Value.(type) {
case *core.Literal_Scalar:
switch scalarValue := literalValue.Scalar.Value.(type) {
case *core.Scalar_Primitive:
switch scalarPrimitive := scalarValue.Primitive.Value.(type) {
case *core.Primitive_Integer:
scalarPrimitiveInt := scalarPrimitive.Integer
return scalarPrimitiveInt, nil
case *core.Primitive_FloatValue:
scalarPrimitiveFloat := scalarPrimitive.FloatValue
return scalarPrimitiveFloat, nil
case *core.Primitive_StringValue:
scalarPrimitiveString := scalarPrimitive.StringValue
return scalarPrimitiveString, nil
case *core.Primitive_Boolean:
scalarPrimitiveBoolean := scalarPrimitive.Boolean
return scalarPrimitiveBoolean, nil
case *core.Primitive_Datetime:
scalarPrimitiveDateTime := scalarPrimitive.Datetime
return scalarPrimitiveDateTime, nil
case *core.Primitive_Duration:
scalarPrimitiveDuration := scalarPrimitive.Duration
return scalarPrimitiveDuration, nil
}
return nil, fmt.Errorf("unsupported literal scalar type %T", scalarValue)
}
case *core.Literal_Collection:
collectionValue := literalValue.Collection.Literals
collection := make([]interface{}, len(collectionValue))
for index, val := range collectionValue {
if collectionElem, err := ExtractFromLiteral(val); err == nil {
collection[index] = collectionElem
} else {
return nil, err
}
}
return collection, nil
case *core.Literal_Map:
mapLiteralValue := literalValue.Map.Literals
mapResult := make(map[string]interface{}, len(mapLiteralValue))
for key, val := range mapLiteralValue {
if val, err := ExtractFromLiteral(val); err == nil {
mapResult[key] = val
} else {
return nil, err
}
}
return mapResult, nil
}
return nil, fmt.Errorf("unsupported literal type %T", literal)
}
104 changes: 104 additions & 0 deletions flyteidl/clients/go/coreutils/extract_literal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// extract_literal_test.go
// Test class for the utility methods which extract a native golang value from a flyte Literal.

package coreutils

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestFetchLiteral(t *testing.T) {
t.Run("Primitive", func(t *testing.T) {
lit, err := MakeLiteral("test_string")
assert.NoError(t, err)
val, err := ExtractFromLiteral(lit)
assert.NoError(t, err)
assert.Equal(t, "test_string", val)
})

t.Run("Array", func(t *testing.T) {
lit, err := MakeLiteral([]interface{}{1, 2, 3})
assert.NoError(t, err)
val, err := ExtractFromLiteral(lit)
assert.NoError(t, err)
arr := []interface{}{int64(1), int64(2), int64(3)}
assert.Equal(t, arr, val)
})

t.Run("Map", func(t *testing.T) {
mapInstance := map[string]interface{}{
"key1": []interface{}{1, 2, 3},
"key2": []interface{}{5},
}
lit, err := MakeLiteral(mapInstance)
assert.NoError(t, err)
val, err := ExtractFromLiteral(lit)
assert.NoError(t, err)
expectedMapInstance := map[string]interface{}{
"key1": []interface{}{int64(1), int64(2), int64(3)},
"key2": []interface{}{int64(5)},
}
assert.Equal(t, expectedMapInstance, val)
})

t.Run("Map_Booleans", func(t *testing.T) {
mapInstance := map[string]interface{}{
"key1": []interface{}{true, false, true},
"key2": []interface{}{false},
}
lit, err := MakeLiteral(mapInstance)
assert.NoError(t, err)
val, err := ExtractFromLiteral(lit)
assert.NoError(t, err)
assert.Equal(t, mapInstance, val)
})

t.Run("Map_Floats", func(t *testing.T) {
mapInstance := map[string]interface{}{
"key1": []interface{}{1.0, 2.0, 3.0},
"key2": []interface{}{1.0},
}
lit, err := MakeLiteral(mapInstance)
assert.NoError(t, err)
val, err := ExtractFromLiteral(lit)
assert.NoError(t, err)
expectedMapInstance := map[string]interface{}{
"key1": []interface{}{float64(1.0), float64(2.0), float64(3.0)},
"key2": []interface{}{float64(1.0)},
}
assert.Equal(t, expectedMapInstance, val)
})

t.Run("NestedMap", func(t *testing.T) {
mapInstance := map[string]interface{}{
"key1": map[string]interface{}{"key11": 1.0, "key12": 2.0, "key13": 3.0},
"key2": map[string]interface{}{"key21": 1.0},
}
lit, err := MakeLiteral(mapInstance)
assert.NoError(t, err)
val, err := ExtractFromLiteral(lit)
assert.NoError(t, err)
expectedMapInstance := map[string]interface{}{
"key1": map[string]interface{}{"key11": float64(1.0), "key12": float64(2.0), "key13": float64(3.0)},
"key2": map[string]interface{}{"key21": float64(1.0)},
}
assert.Equal(t, expectedMapInstance, val)
})

t.Run("Binary", func(t *testing.T) {
s := MakeBinaryLiteral([]byte{'h'})
assert.Equal(t, []byte{'h'}, s.GetScalar().GetBinary().GetValue())
_, err := ExtractFromLiteral(s)
assert.NotNil(t, err)
})

t.Run("NoneType", func(t *testing.T) {
p, err := MakeLiteral(nil)
assert.NoError(t, err)
assert.NotNil(t, p.GetScalar())
_, err = ExtractFromLiteral(p)
assert.NotNil(t, err)
})
}
Loading

0 comments on commit 12df6de

Please sign in to comment.