Skip to content

Commit

Permalink
Move value specific Iterable and Iterator interfaces into core module (
Browse files Browse the repository at this point in the history
…#233)

* Move value specific Iterable and Iterator interfaces into core module

* Update Makefile

Reverted test command

* Update collection.go

* Fixed wrong iterator usage

* Updated use of switch statements
  • Loading branch information
ziflex committed Feb 15, 2019
1 parent 1af8b37 commit f8e061c
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 93 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,4 @@ else
git tag -a v$(RELEASE_VERSION) -m "New $(RELEASE_VERSION) version" && \
git push origin v$(RELEASE_VERSION) && \
goreleaser
endif
endif
6 changes: 3 additions & 3 deletions cli/browser/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ func (flags Flags) List() []string {
continue
}

switch val.(type) {
switch v := val.(type) {
case int:
arg = fmt.Sprintf("--%s=%d", arg, val.(int))
arg = fmt.Sprintf("--%s=%d", arg, v)
case string:
arg = fmt.Sprintf("--%s=%s", arg, val.(string))
arg = fmt.Sprintf("--%s=%s", arg, v)
default:
arg = fmt.Sprintf("--%s", arg)
}
Expand Down
32 changes: 16 additions & 16 deletions pkg/compiler/visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1430,37 +1430,37 @@ func (v *visitor) visit(node antlr.Tree, scope *scope) (core.Expression, error)
var out core.Expression
var err error

switch node.(type) {
switch ctx := node.(type) {
case *fql.BodyContext:
out, err = v.doVisitBody(node.(*fql.BodyContext), scope)
out, err = v.doVisitBody(ctx, scope)
case *fql.ExpressionContext:
out, err = v.doVisitExpression(node.(*fql.ExpressionContext), scope)
out, err = v.doVisitExpression(ctx, scope)
case *fql.ForExpressionContext:
out, err = v.doVisitForExpression(node.(*fql.ForExpressionContext), scope)
out, err = v.doVisitForExpression(ctx, scope)
case *fql.ReturnExpressionContext:
out, err = v.doVisitReturnExpression(node.(*fql.ReturnExpressionContext), scope)
out, err = v.doVisitReturnExpression(ctx, scope)
case *fql.ArrayLiteralContext:
out, err = v.doVisitArrayLiteral(node.(*fql.ArrayLiteralContext), scope)
out, err = v.doVisitArrayLiteral(ctx, scope)
case *fql.ObjectLiteralContext:
out, err = v.doVisitObjectLiteral(node.(*fql.ObjectLiteralContext), scope)
out, err = v.doVisitObjectLiteral(ctx, scope)
case *fql.StringLiteralContext:
out, err = v.doVisitStringLiteral(node.(*fql.StringLiteralContext))
out, err = v.doVisitStringLiteral(ctx)
case *fql.IntegerLiteralContext:
out, err = v.doVisitIntegerLiteral(node.(*fql.IntegerLiteralContext))
out, err = v.doVisitIntegerLiteral(ctx)
case *fql.FloatLiteralContext:
out, err = v.doVisitFloatLiteral(node.(*fql.FloatLiteralContext))
out, err = v.doVisitFloatLiteral(ctx)
case *fql.BooleanLiteralContext:
out, err = v.doVisitBooleanLiteral(node.(*fql.BooleanLiteralContext))
out, err = v.doVisitBooleanLiteral(ctx)
case *fql.NoneLiteralContext:
out, err = v.doVisitNoneLiteral(node.(*fql.NoneLiteralContext))
out, err = v.doVisitNoneLiteral(ctx)
case *fql.VariableContext:
out, err = v.doVisitVariable(node.(*fql.VariableContext), scope)
out, err = v.doVisitVariable(ctx, scope)
case *fql.VariableDeclarationContext:
out, err = v.doVisitVariableDeclaration(node.(*fql.VariableDeclarationContext), scope)
out, err = v.doVisitVariableDeclaration(ctx, scope)
case *fql.FunctionCallExpressionContext:
out, err = v.doVisitFunctionCallExpression(node.(*fql.FunctionCallExpressionContext), scope)
out, err = v.doVisitFunctionCallExpression(ctx, scope)
case *fql.ParamContext:
out, err = v.doVisitParamContext(node.(*fql.ParamContext), scope)
out, err = v.doVisitParamContext(ctx, scope)
default:
err = v.unexpectedToken(node)
}
Expand Down
31 changes: 12 additions & 19 deletions pkg/runtime/collections/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,42 @@ import (
)

type (
Collection interface {
core.Value
// Measurable represents an interface of a value that can has length.
Measurable interface {
Length() values.Int
}

IndexedCollection interface {
Collection
core.Value
Measurable
Get(idx values.Int) core.Value
Set(idx values.Int, value core.Value) error
}

KeyedCollection interface {
Collection
core.Value
Measurable
Keys() []string
Get(key values.String) (core.Value, values.Boolean)
Set(key values.String, value core.Value)
}

IterableCollection interface {
core.Value
Iterate(ctx context.Context) (CollectionIterator, error)
}

CollectionIterator interface {
Next(ctx context.Context) (value core.Value, key core.Value, err error)
}

collectionIteratorWrapper struct {
coreIterator struct {
valVar string
keyVar string
values CollectionIterator
values core.Iterator
}
)

func NewCollectionIterator(
func NewCoreIterator(
valVar,
keyVar string,
values CollectionIterator,
values core.Iterator,
) (Iterator, error) {
return &collectionIteratorWrapper{valVar, keyVar, values}, nil
return &coreIterator{valVar, keyVar, values}, nil
}

func (iterator *collectionIteratorWrapper) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) {
func (iterator *coreIterator) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) {
val, key, err := iterator.values.Next(ctx)

if err != nil {
Expand Down
11 changes: 11 additions & 0 deletions pkg/runtime/core/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ type (
Copy() Value
}

// Iterable represents an interface of a value that can be iterated by using an iterator.
Iterable interface {
Iterate(ctx context.Context) (Iterator, error)
}

// Iterator represents an interface of a value iterator.
// When iterator is exhausted it must return None as a value.
Iterator interface {
Next(ctx context.Context) (value Value, key Value, err error)
}

// Getter represents an interface of
// complex types that needs to be used to read values by path.
// The interface is created to let user-defined types be used in dot notation data access.
Expand Down
12 changes: 6 additions & 6 deletions pkg/runtime/expressions/data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,27 @@ func (ds *DataSource) Iterate(ctx context.Context, scope *core.Scope) (collectio
return collections.NewHTMLNodeIterator(ds.valVariable, ds.keyVariable, data.(values.HTMLNode))
default:
// fallback to user defined types
switch data.(type) {
case collections.IterableCollection:
collection := data.(collections.IterableCollection)
switch collection := data.(type) {
case core.Iterable:
iterator, err := collection.Iterate(ctx)

if err != nil {
return nil, err
}

return collections.NewCollectionIterator(ds.valVariable, ds.keyVariable, iterator)
return collections.NewCoreIterator(ds.valVariable, ds.keyVariable, iterator)
case collections.KeyedCollection:
return collections.NewIndexedIterator(ds.valVariable, ds.keyVariable, data.(collections.IndexedCollection))
return collections.NewKeyedIterator(ds.valVariable, ds.keyVariable, collection)
case collections.IndexedCollection:
return collections.NewKeyedIterator(ds.valVariable, ds.keyVariable, data.(collections.KeyedCollection))
return collections.NewIndexedIterator(ds.valVariable, ds.keyVariable, collection)
default:
return nil, core.TypeError(
data.Type(),
types.Array,
types.Object,
types.HTMLDocument,
types.HTMLElement,
core.NewType("Iterable"),
)
}
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/runtime/expressions/data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package expressions_test

import (
"context"
"github.com/MontFerret/ferret/pkg/runtime/expressions"
"github.com/MontFerret/ferret/pkg/runtime/values"
"testing"

"github.com/MontFerret/ferret/pkg/runtime/collections"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/expressions"
"github.com/MontFerret/ferret/pkg/runtime/values"
. "github.com/smartystreets/goconvey/convey"
)

Expand Down Expand Up @@ -51,7 +51,7 @@ func (c *testIterableCollection) Hash() uint64 {
func (c *testIterableCollection) Copy() core.Value {
return c
}
func (c *testIterableCollection) Iterate(ctx context.Context) (collections.CollectionIterator, error) {
func (c *testIterableCollection) Iterate(ctx context.Context) (core.Iterator, error) {
return &testCollectionIterator{c.values, -1}, nil
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/runtime/values/date_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ func ParseDateTime(input interface{}) (DateTime, error) {
}

func ParseDateTimeWith(input interface{}, layout string) (DateTime, error) {
switch input.(type) {
switch value := input.(type) {
case string:
t, err := time.Parse(layout, input.(string))
t, err := time.Parse(layout, value)

if err != nil {
return DateTime{time.Now()}, err
Expand Down
40 changes: 19 additions & 21 deletions pkg/runtime/values/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,53 +206,51 @@ func SetIn(ctx context.Context, to core.Value, byPath []core.Value, value core.V
}

func Parse(input interface{}) core.Value {
switch input.(type) {
switch value := input.(type) {
case bool:
return NewBoolean(input.(bool))
return NewBoolean(value)
case string:
return NewString(input.(string))
return NewString(value)
case int:
return NewInt(input.(int))
return NewInt(value)
case float64:
return NewFloat(input.(float64))
return NewFloat(value)
case float32:
return NewFloat(float64(input.(float32)))
return NewFloat(float64(value))
case time.Time:
return NewDateTime(input.(time.Time))
return NewDateTime(value)
case []interface{}:
input := input.([]interface{})
arr := NewArray(len(input))
arr := NewArray(len(value))

for _, el := range input {
for _, el := range value {
arr.Push(Parse(el))
}

return arr
case map[string]interface{}:
input := input.(map[string]interface{})
obj := NewObject()

for key, el := range input {
for key, el := range value {
obj.Set(NewString(key), Parse(el))
}

return obj
case []byte:
return NewBinary(input.([]byte))
return NewBinary(value)
case nil:
return None
default:
v := reflect.ValueOf(input)
t := reflect.TypeOf(input)
v := reflect.ValueOf(value)
t := reflect.TypeOf(value)
kind := t.Kind()

if kind == reflect.Slice || kind == reflect.Array {
size := v.Len()
arr := NewArray(size)

for i := 0; i < size; i++ {
value := v.Index(i)
arr.Push(Parse(value.Interface()))
curVal := v.Index(i)
arr.Push(Parse(curVal.Interface()))
}

return arr
Expand All @@ -264,9 +262,9 @@ func Parse(input interface{}) core.Value {

for _, k := range keys {
key := Parse(k.Interface())
value := v.MapIndex(k)
curVal := v.MapIndex(k)

obj.Set(NewString(key.String()), Parse(value.Interface()))
obj.Set(NewString(key.String()), Parse(curVal.Interface()))
}

return obj
Expand All @@ -278,9 +276,9 @@ func Parse(input interface{}) core.Value {

for i := 0; i < size; i++ {
field := t.Field(i)
value := v.Field(i)
fieldValue := v.Field(i)

obj.Set(NewString(field.Name), Parse(value.Interface()))
obj.Set(NewString(field.Name), Parse(fieldValue.Interface()))
}

return obj
Expand Down
6 changes: 3 additions & 3 deletions pkg/stdlib/arrays/append_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestAppend(t *testing.T) {

So(err, ShouldBeNil)
So(out, ShouldNotEqual, arr)
So(out.(collections.Collection).Length(), ShouldBeGreaterThan, arr.Length())
So(out.(collections.Measurable).Length(), ShouldBeGreaterThan, arr.Length())
})

Convey("Should ignore non-unique items", t, func() {
Expand All @@ -39,12 +39,12 @@ func TestAppend(t *testing.T) {

So(err, ShouldBeNil)
So(out, ShouldNotEqual, arr)
So(out.(collections.Collection).Length(), ShouldEqual, arr.Length())
So(out.(collections.Measurable).Length(), ShouldEqual, arr.Length())

out2, err := arrays.Append(context.Background(), arr, values.NewInt(6), values.True)

So(err, ShouldBeNil)
So(out2, ShouldNotEqual, arr)
So(out2.(collections.Collection).Length(), ShouldBeGreaterThan, arr.Length())
So(out2.(collections.Measurable).Length(), ShouldBeGreaterThan, arr.Length())
})
}
4 changes: 2 additions & 2 deletions pkg/stdlib/collections/length.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func Length(_ context.Context, inputs ...core.Value) (core.Value, error) {

value := inputs[0]

c, ok := value.(collections.Collection)
c, ok := value.(collections.Measurable)

if !ok {
return values.None, core.TypeError(value.Type(),
Expand All @@ -28,7 +28,7 @@ func Length(_ context.Context, inputs ...core.Value) (core.Value, error) {
types.HTMLElement,
types.HTMLDocument,
types.Binary,
core.NewType("Collection"),
core.NewType("Measurable"),
)
}

Expand Down
3 changes: 1 addition & 2 deletions pkg/stdlib/html/pagination.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package html
import (
"context"

"github.com/MontFerret/ferret/pkg/runtime/collections"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
Expand Down Expand Up @@ -81,7 +80,7 @@ func (p *Paging) Copy() core.Value {
return values.None
}

func (p *Paging) Iterate(_ context.Context) (collections.CollectionIterator, error) {
func (p *Paging) Iterate(_ context.Context) (core.Iterator, error) {
return &PagingIterator{p.document, p.selector, -1}, nil
}

Expand Down
Loading

0 comments on commit f8e061c

Please sign in to comment.