mirror of
https://github.com/MontFerret/ferret.git
synced 2024-12-14 11:23:02 +02:00
75 lines
1.6 KiB
Go
75 lines
1.6 KiB
Go
package expressions
|
|
|
|
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/pkg/errors"
|
|
)
|
|
|
|
type MemberExpression struct {
|
|
src core.SourceMap
|
|
variableName string
|
|
path []core.Expression
|
|
}
|
|
|
|
func NewMemberExpression(src core.SourceMap, variableName string, path []core.Expression) (*MemberExpression, error) {
|
|
if variableName == "" {
|
|
return nil, errors.Wrap(core.ErrMissedArgument, "variable name")
|
|
}
|
|
|
|
if path == nil || len(path) == 0 {
|
|
return nil, errors.Wrap(core.ErrMissedArgument, "path expressions")
|
|
}
|
|
|
|
return &MemberExpression{src, variableName, path}, nil
|
|
}
|
|
|
|
func (e *MemberExpression) Iterate(ctx context.Context, scope *core.Scope) (collections.Iterator, error) {
|
|
value, err := e.Exec(ctx, scope)
|
|
|
|
if err != nil {
|
|
return nil, core.SourceError(e.src, err)
|
|
}
|
|
|
|
iter, err := collections.ToIterator(value)
|
|
|
|
if err != nil {
|
|
return nil, core.SourceError(e.src, err)
|
|
}
|
|
|
|
return iter, nil
|
|
}
|
|
|
|
func (e *MemberExpression) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) {
|
|
val, err := scope.GetVariable(e.variableName)
|
|
|
|
if err != nil {
|
|
return values.None, core.SourceError(
|
|
e.src,
|
|
err,
|
|
)
|
|
}
|
|
|
|
strPath := make([]core.Value, len(e.path))
|
|
|
|
for idx, exp := range e.path {
|
|
segment, err := exp.Exec(ctx, scope)
|
|
|
|
if err != nil {
|
|
return values.None, err
|
|
}
|
|
|
|
strPath[idx] = segment
|
|
}
|
|
|
|
out, err := values.GetIn(val, strPath)
|
|
|
|
if err != nil {
|
|
return values.None, core.SourceError(e.src, err)
|
|
}
|
|
|
|
return out, nil
|
|
}
|